你的位置:首页 > 软件开发 > ASP.net > C# 异步Socket (BeginXXXX)服务器代码

C# 异步Socket (BeginXXXX)服务器代码

发布时间:2016-07-29 13:00:07
前言:1、最近维护公司的一个旧项目,是Socket通讯的,主要用于接收IPC(客户端)发送上来的抓拍图像,期间要保持通讯,监测数据包并进行处理。但是看之前那人写的代码个人觉得并不是很适合自己,于是就重写了,不过项目暂时弃置了,为了以后能够方便使用,也方便更多像我一样还是渣渣程序员 ...

前言:

1、最近维护公司的一个旧项目,是Socket通讯的,主要用于接收IPC(客户端)发送上来的抓拍图像,期间要保持通讯,监测数据包并进行处理。但是看之前那人写的代码个人觉得并不是很适合自己,于是就重写了,不过项目暂时弃置了,为了以后能够方便使用,也方便更多像我一样还是渣渣程序员的人,记录一些心得。我还是坚信那句话,只有分享才能够进步

 

2、其实在做之前我对这个东西了解也很少,毕竟以我的认识,在国内C#更多地是用来开发网站,于是也在网上看了很多前辈贴的代码,我尝试过直接复制粘贴,发现很多都用不了最后自己写了才发现原来是这么一回事。所以在这里也奉劝各位不要做伸手党,通过自己的理解才能够将别人的知识转变成为自己的资本

 

开始

1、Socket 通信分为同步和异步两种模式,客户端一般用同步,异步多用于服务端。至于两者的区别,很多前辈已经有博客阐述过了,我这里就贴其中一个链接帮助大家理解:http://www.cnblogs.com/BLoodMaster/archive/2010/07/02/1769774.html。万一这个链接失效,相信大家也会搜索到其他资源的

 

2、做这种Socket通信,我觉得关键点在于【数据处理】而不是建立链接,但往往很多不了解人会遇到各种困难,比如Socket链接关闭,丢包,粘包之类的。通用做法就是

  2.1:使用缓冲区,将接收到的字节数组全部储存起来,再去分析数据,获取有效部分。

  2.2:服务器跟客户端需要约定好报文的格式,一般来说至少要有【数据头标识】、【数据实体长度】、【数据尾标识】,这样才能更好地对数据进行处理,否则你很难界定到底哪一段数据才是你想要的。

  2.3:数据分析一定要少用字符串或者字符拆解,因为这样很有可能获取到的长度是错误的(里面有很多空字节,或者编码解码问题导致字符串长度不一致),所以一定要用字节数组来处理,通过约定好的编码解码格式,查找标识所在位置进行数据拆解。【比如:客户端跟服务器连接需要核对身份信息,因此对一字符串进行的特殊加密再编码发送,服务器接收到数据之后如果先编译成了字符串再获取密码转成byte[],长度跟之前记录的很可能就会不一样】。不过对于获取报文头信息这一类通过字符串来拆解更为方便

3、在建立连接时通常发生的问题就是没有循环接收客户端消息导致socket被释放,或者只接受到客户端了几条消息之后就停了,我也遇到过这个问题,所以建立连接的关键在于BeginAccept和BeginReceive两个方法的递归循环调用

4、接下来就是贴代码了,这里只有服务器的,客户端的我还没有做以后补全了会发上来,入口函数是公开的,主要方法全部在这里,至于辅助函数(比如获取IP地址,检查端口是否被占用、获取发送消息大家可以自己去找一下吧,毕竟这些已经有很多前辈开源了)

public void Create_Server_Socket()    {      Thread th_server = null;      get='_blank'>string result = string.Empty;      try      {        socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);        IPAddress ip = Pubilc.Helper.Computer.GetIPv4();        IPEndPoint point = new IPEndPoint(ip, this._port);        socketServer.Bind(point);        socketServer.Listen(this._listen);        th_server = new Thread(() =>        {          if (this._isRunning)            socketServer.BeginAccept(AcceptCallBack, socketServer);          else            Close_Server_Socket();        });        th_server.IsBackground = true;        th_server.Start();      }      catch (Exception ex)      {        if (th_server.IsAlive)          th_server.Abort();        ShowLog(ex.Message);      };    }    public void Close_Server_Socket()    {      if (socketServer != null)      {        socketServer.Close();      }    }    void AcceptCallBack(IAsyncResult ar)    {      Socket socketServer = (Socket)ar.AsyncState;      try      {        Socket socketAccept = socketServer.EndAccept(ar);        DynamicBuffer state = new DynamicBuffer();        state.workSocket = socketAccept;        socketAccept.BeginReceive(state.Buffers, 0, state.Buffers.Length, SocketFlags.None, ReceiveCallBack, state);      }      catch(Exception ex)      {        LogHelper.WriteLog(typeof(SocketHelper_Server), ex);        ShowLog("AcceptCallBack" + ex.Message);      }      finally      {        if (this._isRunning)          socketServer.BeginAccept(AcceptCallBack, socketServer);      }    }    void ReceiveCallBack(IAsyncResult ar)    {      string sendMsg = string.Empty;      DynamicBuffer state = (DynamicBuffer)ar.AsyncState;      Socket socketAccept = state.workSocket;      try      {        int len = socketAccept.EndReceive(ar);        if (len > 0)        {          state.WritBuffer();        }        else        {          sendMsg=doMsg.CheckConnection(socketAccept.RemoteEndPoint.ToString());          if (!string.IsNullOrEmpty(sendMsg))          {            byte[] buffer = Encoding.Default.GetBytes(sendMsg);            state.sb.AddRange(buffer);          }          else          {            socketAccept.Shutdown(SocketShutdown.Both);            socketAccept.Close();          }        }      }      catch (Exception ex)      {        LogHelper.WriteLog(typeof(SocketHelper_Server), ex);        ShowLog("ReceiveCallBack" + ex.Message);      }      finally      {        if (this._isRunning)        {          try          {            Thread th_send = null;            th_send = new Thread(() =>            {              Send(ref state);              th_send.Abort();            });            th_send.IsBackground = true;            th_send.Start();            socketAccept.BeginReceive(state.Buffers, 0, state.Buffers.Length, SocketFlags.None, ReceiveCallBack, state);          }          catch (Exception ex)          {            showLog(ex.Message);            LogHelper.WriteLog(typeof(IpcServerDo), ex);          }        }      }    }    void Send(ref DynamicBuffer state)    {      byte[] buffer = null;      string sendMsg = string.Empty;      Socket socketAccept = state.workSocket;      Dictionary<string, byte[]> data;      state.GetAllData(out data);      if (data.Count > 0)      {        sendMsg = doMsg.AcceptFromIpc(socketAccept.RemoteEndPoint.ToString(), ref data);        if (!string.IsNullOrEmpty(sendMsg))        {          buffer = Encoding.Default.GetBytes(sendMsg.ToCharArray());          socketAccept.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, SendCallBack, socketAccept);        }        Send(ref state);      }    }    void SendCallBack(IAsyncResult ar)    {      Socket socketAccept = (Socket)ar.AsyncState;      try      {        int sendBytes = socketAccept.EndSend(ar);      }      catch(Exception ex)      {        LogHelper.WriteLog(typeof(SocketHelper_Server), ex);      }    }

原标题:C# 异步Socket (BeginXXXX)服务器代码

关键词:C#

C#
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录