zoukankan      html  css  js  c++  java
  • C#的Socket简单实现消息发送

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

    一、先建立Socket的服务类SocketServerManager,用于对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地址,最后是开启新的线程接收和发送消息。

     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统一用字典管理,并封装在SocketInfo的内部类中,消息的发送与接收必须先找到该连接socket。
    最后就是界面的调用,完成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 == "faild")
    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
     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

     

    具体源码(.net4.5,vs2013):具体源码 https://files.cnblogs.com/files/supheart/ServerBySocket.zip

  • 相关阅读:
    WRF WPS预处理
    CVS安装
    Linux窗口最小化消失,任务栏上无法找到的解决方法
    NCARG安装配置出现error while loading shared libraries: libg2c.so.0问题额解决办法
    Netcdf安装
    Embedding R-generated Interactive HTML pages in MS PowerPoint(转)
    The leaflet package for online mapping in R(转)
    Some 3D Graphics (rgl) for Classification with Splines and Logistic Regression (from The Elements of Statistical Learning)(转)
    What does a Bayes factor feel like?(转)
    Weka算法介绍
  • 原文地址:https://www.cnblogs.com/supheart/p/4259707.html
Copyright © 2011-2022 走看看