转载

C#的Socket简单实现消息发送

Socket一般用于网络之间的通信,在这里,实现的是服务端与客户端的简单消息通信。首先是客户端的搭建,一般步骤是先建立Socket绑定本地的IP和端口,并对远端连接进行连接进行监听,这里的监听一般开启后台线程进行循环处理;如果远端有连接到本机的Socket的端口,则获取一个新的Socket对象并重新添加一个线程用于对远端地址进行消息通信(消息的收发),这样,服务端的Socket就简单实现,下面是winForm的具体实现。

一、先建立Socket的服务类SocketServerManager,用于对Socket各种操作的统一管理:

C#的Socket简单实现消息发送
 1     public class SocketManager  2     {  3         Socket _socket = null;  4         EndPoint _endPoint = null;  5         bool _isListening = false;  6         int BACKLOG = 10;  7   8         public SocketManager(string ip, int port)  9         { 10             _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 11             IPAddress _ip = IPAddress.Parse(ip); 12             _endPoint = new IPEndPoint(_ip, port); 13         } 14  15         public void Start() 16         { 17             _socket.Bind(_endPoint); //绑定端口 18             _socket.Listen(BACKLOG); //开启监听 19             Thread acceptServer = new Thread(AcceptWork); //开启新线程处理监听 20             acceptServer.IsBackground = true; 21             _isListening = true; 22             acceptServer.Start(); 23         } 24  25         public void AcceptWork() 26         { 27             while (_isListening) 28             { 29                 Socket acceptSocket = _socket.Accept(); 30                 if (acceptSocket != null) 31                 { 32                     Thread socketConnectedThread = new Thread(newSocketReceive); 33                     socketConnectedThread.IsBackground = true; 34                     socketConnectedThread.Start(acceptSocket); 35                 } 36                 Thread.Sleep(200); 37             } 38         } 39  40         public void newSocketReceive(object obj) 41         { 42             Socket socket = obj as Socket; 43             while (true) 44             { 45                 try 46                 { 47                     if (socket == null) return; 48                     //这里向系统投递一个接收信息的请求,并为其指定ReceiveCallBack做为回调函数  49                     socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallBack, buffer); 50                 } 51                 catch (Exception ex) 52                 { 53                     return; 54                 } 55                 Thread.Sleep(100); 56             } 57         } 58  59         private void ReceiveCallBack(IAsyncResult ar) 60         { 61         } 62     }
public class SockeServertManager

上面是Socket管理类的模型,具体的方法是初始化和开启监听,接下来就是在Form的界面调用建立类和Start方法。

客户端同样是初始化socket,然后就不是监听socket,而是调用Connect连接指定的Socket地址,最后是开启新的线程接收和发送消息。

C#的Socket简单实现消息发送
 1     public class SocketClientManager  2     {  3         public Socket _socket = null;  4         public EndPoint endPoint = null;  5         public bool _isConnected = false;  6   7         public SocketClientManager(string ip, int port)  8         {  9             IPAddress _ip = IPAddress.Parse(ip); 10             endPoint = new IPEndPoint(_ip, port); 11             _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 12         } 13  14         public void Start() 15         { 16             _socket.BeginConnect(endPoint, ConnectedCallback, _socket); 17             _isConnected = true; 18             Thread socketClient = new Thread(SocketClientReceive); 19             socketClient.IsBackground = true; 20             socketClient.Start(); 21         } 22  23         public void SocketClientReceive() 24         { 25             while (_isConnected) 26             { 27                 try { 28                     _socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, buffer); 29                 } 30                 catch (SocketException ex) 31                 { 32                     _isConnected = false; 33                 } 34                  35                 Thread.Sleep(100); 36             } 37         } 38  39         public void ReceiveCallback(IAsyncResult ar) 40         { 41         } 42     }
public class SocketClientManager

主要记住的是,客户端是监听Socket是固定的,是监听绑定地址的,每当有新的连接访问,则开启新的线程与之进行交互,而客户端只简单实现与服务端交互,服务端则只有一个。

Socket的效益发送与接受,一般是通过异步方法BeginReceive和BeginSend进行处理,方法一般带有回调函数,用于执行操作之后的处理。

还有就是连接的关闭,没关闭一个连接,先要暂停在Socket所在的线程方法,我这里的处理是停止掉死循环的函数调用,每当线程所在函数执行完毕,则线程自动销毁。之后就是关闭所连接的socket。

下面是我程序的完整实现,为了方便便利,我把服务器的所有与客户端对话的Socket统一用字典管理,消息的发送与接受必须先找到该连接socket。

最后就是界面的调用,完成Socket的网络消息交互。

下面是具体的实现及源码:

C#的Socket简单实现消息发送
  1     public class SocketManager   2     {   3         public Dictionary<string,SocketInfo> _listSocketInfo = null;   4         Socket _socket = null;   5         public SocketInfo socketInfo = null;   6         EndPoint _endPoint = null;   7         bool _isListening = false;   8         int BACKLOG = 10;   9   10         public delegate void OnConnectedHandler(string clientIP);  11         public event OnConnectedHandler OnConnected;  12         public delegate void OnReceiveMsgHandler(string ip);  13         public event OnReceiveMsgHandler OnReceiveMsg;  14         public event OnReceiveMsgHandler OnDisConnected;  15   16         public SocketManager(string ip, int port)  17         {  18             _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  19             IPAddress _ip = IPAddress.Parse(ip);  20             _endPoint = new IPEndPoint(_ip, port);  21             _listSocketInfo = new Dictionary<string, SocketInfo>();  22         }  23   24         public void Start()  25         {  26             _socket.Bind(_endPoint); //绑定端口  27             _socket.Listen(BACKLOG); //开启监听  28             Thread acceptServer = new Thread(AcceptWork); //开启新线程处理监听  29             acceptServer.IsBackground = true;  30             _isListening = true;  31             acceptServer.Start();  32         }  33   34         public void AcceptWork()  35         {  36             while (_isListening)  37             {  38                 Socket acceptSocket = _socket.Accept();  39                 if (acceptSocket != null && this.OnConnected != null)  40                 {  41                     SocketInfo sInfo = new SocketInfo();  42                     sInfo.socket = acceptSocket;  43                     _listSocketInfo.Add(acceptSocket.RemoteEndPoint.ToString(), sInfo);  44                     OnConnected(acceptSocket.RemoteEndPoint.ToString());  45                     Thread socketConnectedThread = new Thread(newSocketReceive);  46                     socketConnectedThread.IsBackground = true;  47                     socketConnectedThread.Start(acceptSocket);  48                 }  49                 Thread.Sleep(200);  50             }  51         }  52   53         public void newSocketReceive(object obj)  54         {  55             Socket socket = obj as Socket;  56             SocketInfo sInfo = _listSocketInfo[socket.RemoteEndPoint.ToString()];  57             sInfo.isConnected = true;  58             while (sInfo.isConnected)  59             {  60                 try  61                 {  62                     if (sInfo.socket == null) return;  63                     //这里向系统投递一个接收信息的请求,并为其指定ReceiveCallBack做为回调函数   64                     sInfo.socket.BeginReceive(sInfo.buffer, 0, sInfo.buffer.Length, SocketFlags.None, ReceiveCallBack, sInfo.socket.RemoteEndPoint);  65                 }  66                 catch (Exception ex)  67                 {  68                     return;  69                 }  70                 Thread.Sleep(100);  71             }  72         }  73   74         private void ReceiveCallBack(IAsyncResult ar)  75         {  76             EndPoint ep = ar.AsyncState as IPEndPoint;  77             SocketInfo info = _listSocketInfo[ep.ToString()];  78             int readCount = 0;  79             try  80             {  81                 if (info.socket == null) return;  82                 readCount = info.socket.EndReceive(ar);  83             }catch(Exception ex){  84                 return;  85             }  86             if (readCount > 0)  87             {  88                 //byte[] buffer = new byte[readCount];  89                 //Buffer.BlockCopy(info.buffer, 0, buffer, 0, readCount);  90                 if (readCount < info.buffer.Length)  91                 {  92                     byte[] newBuffer = new byte[readCount];  93                     Buffer.BlockCopy(info.buffer, 0, newBuffer, 0, readCount);  94                     info.msgBuffer = newBuffer;  95                 }  96                 else  97                 {  98                     info.msgBuffer = info.buffer;  99                 } 100                 string msgTip = Encoding.ASCII.GetString(info.msgBuffer); 101                 if (msgTip == "/0/0/0faild") 102                 { 103                     info.isConnected = false; 104                     if (this.OnDisConnected != null) OnDisConnected(info.socket.RemoteEndPoint.ToString()); 105                     _listSocketInfo.Remove(info.socket.RemoteEndPoint.ToString()); 106                     info.socket.Close(); 107                     return; 108                 } 109                 if (OnReceiveMsg != null) OnReceiveMsg(info.socket.RemoteEndPoint.ToString()); 110             } 111         } 112  113         public void SendMsg(string text, string endPoint) 114         { 115             if (_listSocketInfo.Keys.Contains(endPoint) && _listSocketInfo[endPoint] != null) 116             { 117                 _listSocketInfo[endPoint].socket.Send(Encoding.ASCII.GetBytes(text)); 118             } 119         } 120  121         public void Stop() 122         { 123             _isListening = false; 124             foreach (SocketInfo s in _listSocketInfo.Values) 125             { 126                 s.socket.Close(); 127             } 128         } 129  130         public class SocketInfo 131         { 132             public Socket socket = null; 133             public byte[] buffer = null; 134             public byte[] msgBuffer = null; 135             public bool isConnected = false; 136  137             public SocketInfo() 138             { 139                 buffer = new byte[1024 * 4]; 140             } 141         } 142     }
public class SocketServerManager
C#的Socket简单实现消息发送
 1     public class SocketClientManager  2     {  3         public Socket _socket = null;  4         public EndPoint endPoint = null;  5         public SocketInfo socketInfo = null;  6         public bool _isConnected = false;  7   8         public delegate void OnConnectedHandler();  9         public event OnConnectedHandler OnConnected; 10         public event OnConnectedHandler OnFaildConnect; 11         public delegate void OnReceiveMsgHandler(); 12         public event OnReceiveMsgHandler OnReceiveMsg; 13  14         public SocketClientManager(string ip, int port) 15         { 16             IPAddress _ip = IPAddress.Parse(ip); 17             endPoint = new IPEndPoint(_ip, port); 18             _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 19         } 20  21         public void Start() 22         { 23             _socket.BeginConnect(endPoint, ConnectedCallback, _socket); 24             _isConnected = true; 25             Thread socketClient = new Thread(SocketClientReceive); 26             socketClient.IsBackground = true; 27             socketClient.Start(); 28         } 29  30         public void SocketClientReceive() 31         { 32             while (_isConnected) 33             { 34                 SocketInfo info = new SocketInfo(); 35                 try { 36                     _socket.BeginReceive(info.buffer, 0, info.buffer.Length, SocketFlags.None, ReceiveCallback, info); 37                 } 38                 catch (SocketException ex) 39                 { 40                     _isConnected = false; 41                 } 42                  43                 Thread.Sleep(100); 44             } 45         } 46  47         public void ReceiveCallback(IAsyncResult ar) 48         { 49             socketInfo = ar.AsyncState as SocketInfo; 50             if (this.OnReceiveMsg != null) OnReceiveMsg(); 51         } 52  53         public void ConnectedCallback(IAsyncResult ar) 54         { 55             Socket socket = ar.AsyncState as Socket; 56             if (socket.Connected) 57             { 58                 if (this.OnConnected != null) OnConnected(); 59             } 60             else 61             { 62                 if (this.OnFaildConnect != null) OnFaildConnect(); 63             } 64         } 65  66         public void SendMsg(string msg) 67         { 68             byte[] buffer = Encoding.ASCII.GetBytes(msg); 69             _socket.Send(buffer); 70         } 71  72         public class SocketInfo 73         { 74             public Socket socket = null; 75             public byte[] buffer = null; 76  77             public SocketInfo() 78             { 79                 buffer = new byte[1024 * 4]; 80             } 81         } 82     }
public class SocketClientManager

C#的Socket简单实现消息发送

正文到此结束
Loading...