一、简介
随着WEB技术的发展,很多本是用Sockets完成的功能,基本上可以用WEB技术来替代了,Sockets通信技 术逐渐被人们遗忘,而Sockest的应用却也有它独有的优势。网络服务如Internet时间同步、IM工具如MSN与QQ、短信网关如中国移动、中国联通等都采用的是SOCKETs,在信息化发达的今天,很多也想着利用SOCKETs来开发出属于自己的通信工具。
DONET的System.Net.Sockets命名空间类中封闭了大量的Socket类,此命名空间中用简单的方法对复杂的Sockets进行了连接与通讯。我们一起来建立一个基于System.Net.Sockets的通用类库,并基于此学习一下如何使用该类库。
开发环境:Microsoft Framework 2.0
开发工具:Microsoft Visual Studio 2008
二、创建
1、创建一个名为WFASocketsSolution的空白解决方案并在该方案中创建名为SocketsLib的类库及SocketFactory类。


2、在该解决方案下创建一个名为WFASocketsSample的Windows窗体应用程序项目并将其设为启动项目
3、在SocketsLib项目中新建名为SocketsConnection的类,为Sockets的连接类,并在此类中添加NetWorkStream和ConnectionName。分别表示一个连接的名字和它包含的NetWorkStream。
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
namespace SocketsLib
{
public class SocketsConnection
{
#region private fields
private NetworkStream _networkStream;
private String _connectionName;
#endregion
#region public property
public NetworkStream NetworkStream
{
get { return _networkStream; }
set { _networkStream = value; }
}
public String ConnectionName
{
get { return _connectionName; }
set { _connectionName = value; }
}
#endregion
#region Constructor
public SocketsConnection(NetworkStream networkStream,string connectionName)
{
this._networkStream = networkStream;
this._connectionName = connectionName;
}
public SocketsConnection(NetworkStream networkStream)
: this(networkStream, string.Empty)
{
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace SocketsLib
{
public class ConnectionCollection:List<SocketsConnection>
{
}
}
5、新建一名为SocketsServer的类,用于侦听网络连接
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
namespace SocketsLib
{
public class SocketsServer
{
#region private fields
private ConnectionCollection _connections;
private TcpListener _listener;
#endregion
#region public properties
public ConnectionCollection Connections
{
get { return _connections; }
set { _connections = value; }
}
public TcpListener Listener
{
get { return _listener; }
set { _listener = value; }
}
#endregion
#region constructor
public SocketsServer(TcpListener listener)
{
this._connections = new ConnectionCollection();
this._listener = listener;
}
#endregion
#region public function
public void Start()
{
while (true)
{
if (_listener.Pending())
{
TcpClient client = _listener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
this._connections.Add(new SocketsConnection(stream));
}
}
}
#endregion
}
6、在SocketsFactory类中声明一个私有变量_serverListenThread,并加入StartServer方法。当执行此方法时,初始化_ serverListenThread并在此线程中开始侦听网络连接
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace SocketsLib
{
public class SocketsFactory
{
#region private fields
System.Threading.Thread _serverListenThread;
#endregion
#region public function
public void StartServer(int port)
{
TcpListener listener = new TcpListener(IPAddress.Any, port);
listener.Start();
SocketsServer server = new SocketsServer(listener);
_serverListenThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(server.Start));
_serverListenThread.Start();
}
#endregion
}
}
6、做到此处,需要做一个测试,看线程是否能够正常的工作,在窗体项目中添加一窗体类SampleForm,并在SampleForm_Load方法中添加如下代码
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WFASocketsSample
{
public partial class SampleForm : Form
{
public SampleForm()
{
InitializeComponent();
}
private void SampleForm_Load(object sender, EventArgs e)
{
SocketsLib.SocketsFactory factory = new SocketsLib.SocketsFactory();
factory.StartServer(1979);
}
}
}
在SocketsServer中的Start中加了断点后进行Debug,得到下图,我们可以看到线程已经启动,并开始监听了。

7、下面我们启动另外一个Visual Studio 2008实例,创建一个名为WFASocketsTestSolution的解决方案,将SocketsLib项目包含进来并创建一个名为WFASocketsTest的Windows应用程序

8、在SocketsLib项目中创建名为Client的类
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace SocketsLib
{
public class Client
{
#region public fields
public const int CONNECTTIMEOUT = 10;
public SocketsConnection connection;
#endregion
#region constructor
public Client()
{
}
#endregion
#region public function
public static SocketsConnection StartClient(IPAddress ipaddress, int port)
{
TcpClient client = new TcpClient();
client.SendTimeout = CONNECTTIMEOUT;
client.ReceiveTimeout = CONNECTTIMEOUT;
client.Connect(ipaddress, port);
return new SocketsConnection(client.GetStream());
}
#endregion
}
}
9、在SocketFactory中加入StartClient函数
public SocketsConnection StartClient(IPAddress ip, int port)
{
return Client.StartClient(ip, port);
} 10、在项目的窗体类的TestForm_Load方法中加入如下代码,然后,先执行WFASocketsSample项目,然后执行此项目,如果没有报错,则表明连接成功。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SocketsLib;
namespace WFASocketsTest
{
public partial class TestForm : Form
{
private SocketsConnection _connection;
public TestForm()
{
InitializeComponent();
}
private void TestForm_Load(object sender, EventArgs e)
{
SocketsFactory factory = new SocketsFactory();
_connection = factory.StartClient(System.Net.IPAddress.Parse("192.168.0.2"), 1979);
}
}
}
11、OK,现在客户端可以连上服务端了,下面,我们就开始构建有我们能看得见摸得着的功能——发送信息。但可以看得出,目前我们还未有任何发送信息的方法。所以,我们在SocketsFactory类中构建一个发送消息的静态方法,
#region static function
public static void SendMessage(string message, SocketsConnection connection)
{
byte[] buffer = Encoding.UTF8.GetBytes(message);
connection.NetworkStream.Write(buffer, 0, buffer.Length);
}
#endregion
12、现在我们可以利用此方法来发送消息了。当然,在测试之前,我们要在服务器端的侦听模块中加入侦听信息的功能
public void Listenning()
{
while (true)
{
System.Threading.Thread.Sleep(2000);
foreach (SocketsConnection connection in this._connections)
{
if (connection.NetworkStream.CanRead && connection.NetworkStream.DataAvailable)
{
byte[] buffer = new byte[1024];
int count = connection.NetworkStream.Read(buffer, 0, buffer.Length);
Console.Write(Encoding.UTF8.GetString(buffer, 0, buffer.Length));
}
}
}
}
以上是SocketsServer类中需添加的私的变量及修改的StartServer方法
private System.Threading.Thread _listenningthread;
public void StartServer(int port)
{
TcpListener listener = new TcpListener(IPAddress.Any, port);
listener.Start();
SocketsServer server = new SocketsServer(listener);
_serverListenThread = new System.Threading.Thread(new System.Threading.ThreadStart(server.Start));
_listenningthread = new System.Threading.Thread(new System.Threading.ThreadStart(server.Listenning));
_serverListenThread.Start();
_listenningthread.Start();
}
以上是SocketsFactory类中需添加的代码
13、在SocketsFactory类中加入StartListen方法,并在TestForm_Load事件中加入如下代码:
SocketsFactory.SendMessage("Hello World!", _connection);
14、再运行服务端与客户端。即可看到如下结果:


14、当我们看到输出窗口中出现了Hello World!时,表明通信成功。(下载源代码)
625

被折叠的 条评论
为什么被折叠?



