关于socket 的学习

こ雲淡風輕ζ 提交于 2020-03-22 03:47:37

在前一篇讲到了服务侦听,具体构建了一个抽象类,该类是后续服务类中SOCKET通讯服务的基类,而SOCKET通讯中不论是服务端还是客户端都需要数据收发,客户端对应服务端侦听的部份则是连接,下面就讲讲连接和数据收发

1.连接

  该部份比较简单,只有三个简单的函数:CreateConnectToRemoteSocket,ConnectToRemoteCore,AsyncConnectToRemoteCore,

   CreateConnectToRemoteSocket:创建连接的Socket,其中CheckSockectIsConnected是检查是否已连接(该函数用了MS使用的例子来判断是否已连接),最后使用传进的参数(如果不为null)设置SOCKET(比如超时等等),TcpIPSocketSetting类是一个专用户设置SOCKET的类

   ConnectToRemoteCore:同步连接到远程

   AsyncConnectToRemoteCore:异步连接到远程,在该函数中用到类接口ITranseParamets,使用SocketAsyncEventArgs.UserToken存储该接口参数,对于该接口的定义我会在代码中贴出,并且属性及方法也会在该接口中说明,其实现会在后续章节中讲到,SocketAsyncEventArgs.RemoteEndPoint存储要连接到的远程终结点(这个一定要设),最后调用Socket.ConnectAsync函数异步连接,该函数使用的参数及返回值的含义等同上一章使用到的Socket.AcceptAsync,在Socket中类似这样的还有收发函数Socket.SendAsync,Socket.ReceiveAsync,这些函数都使用SocketAsyncEventArgs类,返回值都是Bool类型,含义及处理都类型上一章的Socket.AcceptAsync,只是在调用前设置SocketAsyncEventArgs类的方法不同(而所有方法中都必需设置SocketAsyncEventArgs.Completed事件),及返回后SocketAsyncEventArgs类的有效属性不同,本例中是在GetSocketArg方法中设置了SocketAsyncEventArgs类的属性,由于GetSocketArg是一个通用方法,其实在本例中它仅设置类SocketError属性及Completed事件,其它属性都是null,本例中Socket.ConnectAsync方法完成后的有效属性:它完成后仅SocketError属性有效指示是否成功

  OnCompleted:Completed事件处理程序,该例程是连接及数据收发的处理例程,先讲连接的处理例程,仅仅调用OnConnectCompleted方法完成连接

OverAsyncTranse:该例程用于完成异步操作,它在连接及收发操作中都会调用,首先RecySocketAsyncEventArgs,回收SocketAsyncEventArgs,如果你的SocketAsyncEventArgs不是使用缓冲的则不必调用了,设置ITranseParamets.TranseError指示是否有错误,调用ITranseParamets.AsyncTranseOver通指异步操作完成

2.数据收发的约定

   数据的收发方都遵循约定ITranseHeader,该接口是一个约定,及传输过程中的控制信息,实现该接口的类负责解读该约定的含义,而该接口在网络中传输的数据则存储在该接口的Data属性中,Data属性应该是一个接收双方都已知长度的字节数组,通常方送方事先填充Data,接收方根据双方已知的字节长度接收该长度字节数的内容,具体说命见代码中贴出的说明,

其实现会在后续章节中给出,其实这个就类似于数据传输协议的头

3.数据的收发

  数据收发分为同步和异步两种,这两种都用同一规则操作,只不过途经不同而已,它们都是:先发送(接收)约定,然后根据约定发送(接收)数据体,同步接收和发送比较简单,分别是SendDataCore,ReceiveDataCore这两个例程,而它们又都各自调用SendHeaderCore和ReceiveHeaderCore来发送(接收)约定

  PrepareForSend:发送前准备,将要发送的数据读到发送缓冲区,这个例程同步和异步都使用,看过程就应该知道起含义,这里就不说了

  HandlerReceiver:接收数据后的处理,该例程将接收到的字节数rcvsize写进流中,并根据约定返回是否还有后续数据要接收,同样这个例程同步异步都使用

  数据异步的收发:AsyncSendDataCore和AsyncRecevDataCore分别发送和接收约定,NextAsyncSendDataCore和NextAsyncReceiveDataCore分别根据约定发送和接收数据体,返回True说明还有后续数据需要发送或接收,否则说明数据发送或接收完成,HeaderIsTranseOver例程判断约定是否已发送或接收完成,在异步数据收发中最重要的是设置每次要发送或接收的数据缓冲区(该缓冲区在给出SocketAsyncEventArgs就已设为ITranseParamets.TranseBuffer)及偏移量和长度,而偏移量及长度分别在发送和接收前设置

OnCompleted:数据异步接收和发送事件处理

   约定完成前调用OnHeaderCompleted,约定完成后调用OnTranseDataCompleted,这两个例程都是判断指定操作是否已完成,未完成则继续下一轮操作,OnHeaderCompleted例程中已完成则开始根据约定开始数据主体收发操作,OnTranseDataCompleted例程中完成则调用OverAsyncTranse结束异步操作

3.其它

   ITranseInterface接口是为了以后扩展数据传输而定义的接口(例如不使用Socket的数据传输),在使用中仅使用该接口而不管其实现,这样方便以后扩展

   本类中TranseInterfaceDirection枚举是为了区分该传输接口是客户端连接发起方还是服务端被动接受连接方,分别提供两个构造,带参数的构造一定是服务端被动接收端,不带参数的构造则是客户端发起连接方

WaitClose方法和Close方法:前一个方法是等待远程方调用Close后才关闭,其实现机理是首先开始异步接收1长度数据等待对方关闭时肯定在回调中引发错误,此时关闭.

以下为代码:

 

TcpIpTranseInterface
  1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5 using System.Net.Sockets;  6 using System.IO;  7 using System.Net;  8   9 namespace YZKStdLibrary.Network.Transe 10 { 11     public class TcpIpTranseInterface : ITranseInterface 12     { 13  14   static TcpIpTranseInterface() 15         { 16             StateSendBytes = new byte[1]; 17             SocketArgPools = new RecyManager<SocketAsyncEventArgs>(50); 18             WaitCloseBytes = new byte[1]; 19         } 20  21         public TcpIpTranseInterface() 22         { 23             p_TranseDirection = TranseInterfaceDirection.Client; 24         } 25  26         public TcpIpTranseInterface( 27             Socket socket) 28         { 29             g_TcpSocket = socket; 30             p_TranseDirection = TranseInterfaceDirection.Server; 31         } 32  33         internal Socket BaseSocket 34         { 35             get { return g_TcpSocket; } 36         } 37  38         #region 私有变量 39  40         private Socket g_TcpSocket; 41  42         private TranseInterfaceDirection p_TranseDirection; 43  44         private static readonly byte[] StateSendBytes; 45  46         private static readonly byte[] WaitCloseBytes; 47  48         public static readonly RecyManager<SocketAsyncEventArgs> SocketArgPools; 49  50         #endregion 51  52         #region ITranseInterfaceInformation 成员 53         /// <summary> 54 /// 获取本地终结点信息 55 /// </summary> 56         public EndPoint LocalEndPont 57         { 58             get 59             { 60                 if (g_TcpSocket != null) 61                     return g_TcpSocket.LocalEndPoint; 62                 else 63                     return null; 64             } 65         } 66         /// <summary> 67 /// 获取远程终结点信息 68 /// </summary> 69         public EndPoint RemoteEndPoint 70         { 71             get 72             { 73                 if (g_TcpSocket != null) 74                     return g_TcpSocket.RemoteEndPoint; 75                 else 76                     return null; 77             } 78         } 79         /// <summary> 80 /// 获取当前传输接口建立连接时的方向 81 /// </summary> 82         public TranseInterfaceDirection TranseDirection 83         { 84             get { return p_TranseDirection; } 85         } 86         /// <summary> 87 /// 获取传输协义名称 88 /// </summary> 89         public string ProtocolTypeName 90         { 91             get { return TranseProtocolTypeNames.TcpIp; } 92         } 93  94         #endregion 95  96         #region 接收前和发送后流处理 97  98         /// <summary> 99 /// 返回小于等于0值指示无数据发送100 /// 会设置paramets.BytesTransferred101 /// </summary>102 /// <param name="paramets"></param>103 /// <returns></returns>104         private int PrepareForSend(ITranseParamets paramets)105         {106             int rd = paramets.TranseStream.Read(107                 paramets.TranseBuffer, paramets.TranseBufferOffset, paramets.TranseBufferSize);108             if (rd > 0)109             {110                 paramets.BytesTransferred =111                     paramets.BytesTransferred + rd;112             }113             return rd;114         }115 116         /// <summary>117 /// 返回True指示已接收完成118 /// 会设置paramets.BytesTransferred119 /// </summary>120 /// <param name="paramets"></param>121 /// <param name="rcvsize"></param>122 /// <returns></returns>123         private bool HandlerReceiver(ITranseParamets paramets,int rcvsize)124         {125             if (rcvsize > 0)126             {127                 paramets.TranseStream.Write(paramets.TranseBuffer,128                        paramets.TranseBufferOffset, rcvsize);129                 paramets.BytesTransferred =130                    paramets.BytesTransferred + rcvsize;131             }132             return paramets.TranseHeader.TranseSize <= paramets.BytesTransferred;133         }134         #endregion135 136         #region 数据同步接收和发送137 138         private void SendHeaderCore(139             ITranseHeader header)140         {141             int offset = 0;142             int l = header.Data.Length;143             while (l > 0)144             {145                 int s = g_TcpSocket.Send(header.Data, offset, l, SocketFlags.None);146                 l -= s;147                 offset += s;148             }149         }150 151         private void SendDataCore(ITranseParamets paramets)152         {153             SendHeaderCore(paramets.TranseHeader);154             paramets.HeaderTransed();155             int x = PrepareForSend(paramets);156             while (x > 0)157             {158                 while (x > 0)159                 {160                     int offset = paramets.TranseBufferOffset;161                     int s = g_TcpSocket.Send(paramets.TranseBuffer,162                         offset, x, SocketFlags.None);163                     x -= s;164                     offset += s;165                 }166                 x = PrepareForSend(paramets);167             }168         }169 170         private void ReceiveHeaderCore(171             ITranseHeader header)172         {173             int l = header.Data.Length;174             int offset = 0;175             while (l > 0)176             {177                 int s = g_TcpSocket.Receive(header.Data, offset, l, SocketFlags.None);178                 l -= s;179                 offset += s;180             }181             header.ResetParametsFromData();182         }183 184         private void ReceiveDataCore(ITranseParamets paramets)185         {186             ReceiveHeaderCore(paramets.TranseHeader);187             paramets.HeaderTransed();188             int rcvsize = 0;189             while (!HandlerReceiver(paramets, rcvsize))190             {191                 long x = paramets.TranseHeader.TranseSize - paramets.BytesTransferred;192                 if (x > paramets.TranseBufferSize)193                     x = paramets.TranseBufferSize;194                 rcvsize = g_TcpSocket.Receive(paramets.TranseBuffer,195                     paramets.TranseBufferOffset, (int)x, SocketFlags.None);196             }197         }198         #endregion199 200         #region 异步处理201 202         private void CopyHeaderDataToTranseBuffer(203             ITranseParamets par,SocketAsyncEventArgs arg)204         {205             int hs = par.TranseHeader.Data.Length;206             arg.SetBuffer(arg.Offset, hs);207             Array.Copy(par.TranseHeader.Data, 0, arg.Buffer,208                 arg.Offset, arg.Count);209         }210 211         private void CopyTranseBufferToHeaderData(212             ITranseParamets par, SocketAsyncEventArgs arg)213         {214             int hs = par.TranseHeader.Data.Length;215             Array.Copy(arg.Buffer, arg.Offset,216                 par.TranseHeader.Data, 0, hs);217             par.TranseHeader.ResetParametsFromData();218         }219 220         private SocketAsyncEventArgs GetSocketArg(221             ITranseParamets par)222         {223             SocketAsyncEventArgs arg = SocketArgPools.GetItem();224             arg.SetBuffer(par.TranseBuffer, par.TranseBufferOffset, par.TranseBufferSize);225             arg.Completed += new EventHandler<SocketAsyncEventArgs>(OnCompleted);226             arg.SocketError = SocketError.Success;227             return arg;228         }229 230         private void RecySocketAsyncEventArgs(SocketAsyncEventArgs arg)231         {232             arg.Completed -= new EventHandler<SocketAsyncEventArgs>(OnCompleted);233             arg.SetBuffer(null, 0, 0);234             arg.UserToken = null;235             arg.AcceptSocket = null;236             arg.RemoteEndPoint = null;237             SocketArgPools.RecyItem(arg);238         }239 240         private void OverAsyncTranse(241             SocketAsyncEventArgs arg,242             ITranseParamets paramets,243             Exception error)244         {245             RecySocketAsyncEventArgs(arg);246             paramets.TranseError = error;247             paramets.AsyncTranseOver();248         }249 250         private void OnCompleted(object sender, SocketAsyncEventArgs e)251         {252             ITranseParamets par = e.UserToken as ITranseParamets;253             if (par.DataTranseDirection != DataTranseDirection.Connecting)254             {255                 if (e.BytesTransferred == 0)256                 {257                     if (!CheckSockectIsConnected())258                         e.SocketError = SocketError.ConnectionAborted;259                 }260             }261             if (e.SocketError != SocketError.Success)262             {263                 OverAsyncTranse(e, par, new SocketException((int)e.SocketError));264                 return;265             }266             switch (par.DataTranseDirection)267             {268                 case DataTranseDirection.Connecting:269                     {270                         OnConnectCompleted(par,e);271                         break;272                     }273                 case DataTranseDirection.ReceivingData:274                 case DataTranseDirection.SendingData:275                     {276                         if (par.HeaderTransedOver)277                             OnTranseDataCompleted(par,e);278                         else279                             OnHeaderCompleted(par,e);280                         break;281                     }282             }283         }284 285         private void OnHeaderCompleted(ITranseParamets paramets,SocketAsyncEventArgs e)286         {287             bool ovcall = false;288             switch (e.LastOperation)289             {290                 case SocketAsyncOperation.Send:291                     {292                         try293                         {294                             if (!HeaderIsTranseOver(paramets, e))295                             {296                                 if (!g_TcpSocket.SendAsync(e))297                                     OnCompleted(g_TcpSocket, e);298                                 return;299                             }300                             paramets.HeaderTransed();301                             if (!NextAsyncSendDataCore(paramets, e))302                             {303                                 paramets.AsyncNotyTransing();304                                 ovcall = true;305                                 OverAsyncTranse(e, paramets, null);306                             }307                         }308                         catch (Exception err)309                         {310                             if (!ovcall)311                                 OverAsyncTranse(e, paramets, err);312                         }313                         break;314                     }315                 case SocketAsyncOperation.Receive:316                     {317                         try318                         {319                             if (!HeaderIsTranseOver(paramets, e))320                             {321                                 if (!g_TcpSocket.ReceiveAsync(e))322                                     OnCompleted(g_TcpSocket, e);323                                 return;324                             }325                             CopyTranseBufferToHeaderData(paramets, e);326                             paramets.HeaderTransed();327                             if (!NextAsyncReceiveDataCore(paramets, e))328                             {329                                 ovcall = true;330                                 OverAsyncTranse(e, paramets, null);331                             }332                         }333                         catch (Exception err)334                         {335                             if (!ovcall)336                                 OverAsyncTranse(e, paramets, err);337                         }338                         break;339                     }340             }341         }342 343         private void OnConnectCompleted(ITranseParamets paramets,SocketAsyncEventArgs e)344         {345             OverAsyncTranse(e, paramets, null);346         }347 348         private void OnTranseDataCompleted(ITranseParamets paramets,SocketAsyncEventArgs e)349         {350             bool ovcall = false;351             switch (e.LastOperation)352             {353                 case SocketAsyncOperation.Send:354                     {355                         try356                         {357                             paramets.AsyncNotyTransing();358                             if (!NextAsyncSendDataCore(paramets, e))359                             {360                                 ovcall = true;361                                 OverAsyncTranse(e, paramets, null);362                             }363                         }364                         catch (Exception err)365                         {366                             if (!ovcall)367                                 OverAsyncTranse(e, paramets, err);368                         }369                         break;370                     }371                 case SocketAsyncOperation.Receive:372                     {373                         try374                         {375                             bool hd = HandlerReceiver(paramets, e.BytesTransferred);376                             paramets.AsyncNotyTransing();377                             if (hd)378                             {379                                 ovcall = true;380                                 OverAsyncTranse(e, paramets, null);381                             }382                             else383                             {384                                 NextAsyncReceiveDataCore(paramets, e);385                             }386                         }387                         catch (Exception err)388                         {389                             if (!ovcall)390                                 OverAsyncTranse(e, paramets, err);391                         }392                         break;393                     }394             }395         }396 397         #endregion398 399     }400 401 }
TcpIpTranseInterface
  1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5 using System.Net.Sockets;  6 using System.IO;  7 using System.Net;  8   9 namespace YZKStdLibrary.Network.Transe 10 { 11     partial class TcpIpTranseInterface : ITranseInterface 12     { 13  #region 数据异步接收和发送 14  15         private bool NextAsyncSendDataCore(ITranseParamets paramets, SocketAsyncEventArgs e) 16         { 17             int s = PrepareForSend(paramets); 18             if (s > 0) 19             { 20                 if (s > paramets.TranseBufferSize) 21                     s = paramets.TranseBufferSize; 22                 e.SetBuffer(e.Offset, s); 23                 if (!g_TcpSocket.SendAsync(e)) 24                     OnCompleted(g_TcpSocket, e); 25                 return true; 26             } 27             return false; 28         } 29  30         private void AsyncSendDataCore(ITranseParamets par) 31         { 32             SocketAsyncEventArgs arg = GetSocketArg(par); 33             arg.UserToken = par; 34             CopyHeaderDataToTranseBuffer(par, arg); 35             if (!g_TcpSocket.SendAsync(arg)) 36                 OnCompleted(g_TcpSocket, arg); 37         } 38  39         private void AsyncRecevDataCore(ITranseParamets par) 40         { 41             SocketAsyncEventArgs arg = GetSocketArg(par); 42             arg.UserToken = par; 43             arg.SetBuffer(arg.Offset, par.TranseHeader.Data.Length); 44             if (!g_TcpSocket.ReceiveAsync(arg)) 45                 OnCompleted(g_TcpSocket, arg); 46         } 47  48         private bool NextAsyncReceiveDataCore(ITranseParamets paramets, SocketAsyncEventArgs e) 49         { 50             long dx = paramets.TranseHeader.TranseSize - paramets.BytesTransferred; 51             if (dx > 0) 52             { 53                 if (dx > paramets.TranseBufferSize) 54                     dx = paramets.TranseBufferSize; 55                 e.SetBuffer(e.Offset, (int)dx); 56                 if (!g_TcpSocket.ReceiveAsync(e)) 57                     OnCompleted(g_TcpSocket, e); 58                 return true; 59             } 60             return false; 61         } 62  63         private bool HeaderIsTranseOver(ITranseParamets paramets, SocketAsyncEventArgs e) 64         { 65             int dx = e.Count - e.BytesTransferred; 66             if (dx > 0) 67             { 68                 int offset = e.Offset + e.BytesTransferred; 69                 e.SetBuffer(offset, dx); 70                 return false; 71             } 72             else 73                 e.SetBuffer(paramets.TranseBufferOffset, paramets.TranseBufferSize); 74             return true; 75         } 76         #endregion 77  78         #region 异步等待对方关闭 79  80         private void WaitCloseCore(object state, WaitCloseDelegate callback) 81         { 82             lock (g_CloseAsyncLock) 83             { 84                 if (g_TcpSocket != null 85                     && !p_ClosedOver) 86                     g_TcpSocket.BeginReceive(WaitCloseBytes, 87                         0, 1, SocketFlags.None, WaitCloseCallback, new waitCloseParamets(state, callback)); 88             } 89         } 90  91         private void WaitCloseCallback(IAsyncResult ir) 92         { 93             waitCloseParamets callback = ir.AsyncState as waitCloseParamets; 94             lock (g_CloseAsyncLock) 95             { 96                 if (!p_ClosedOver) 97                 { 98                     try 99                     {100                         g_TcpSocket.EndReceive(ir);101                     }102                     catch { }103                 }104             }105             CloseCore(false);106             //g_TcpSocket = null;107             if (callback.Callback != null)108                 callback.Callback(callback.State);109         }110 111         private class waitCloseParamets112         {113             internal waitCloseParamets(object userstate, WaitCloseDelegate usercallback)114             {115                 state = userstate;116                 callback = usercallback;117             }118 119             private object state;120 121             private WaitCloseDelegate callback;122 123             public object State124             {125                 get { return state; }126             }127 128             public WaitCloseDelegate Callback129             {130                 get131                 {132                     return callback;133                 }134             }135         }136         #endregion137 138         #region 连接139 140         private void CreateConnectToRemoteSocket(TcpIPSocketSetting setting)141         {142             if (CheckSockectIsConnected())143                 throw new InvalidOptionException("已连接");144             lock (g_CloseAsyncLock)145             {146                 p_ClosedOver = false;147                 g_TcpSocket = new Socket(AddressFamily.InterNetwork,148                      SocketType.Stream, ProtocolType.Tcp);149             }150             if (setting != null)151                 setting.AppSetting(g_TcpSocket);152         }153 154         private void ConnectToRemoteCore(EndPoint remoteEp, TcpIPSocketSetting setting)155         {156             CreateConnectToRemoteSocket(setting);157             g_TcpSocket.Connect(remoteEp);158         }159 160         private void AsyncConnectToRemoteCore(ITranseParamets par)161         {162             CreateConnectToRemoteSocket(par.ConnectTranseInterfaceSetting as TcpIPSocketSetting);163             SocketAsyncEventArgs arg = GetSocketArg(par);164             arg.UserToken = par;165             arg.RemoteEndPoint = par.ConnectToEndPoint;166             if (!g_TcpSocket.ConnectAsync(arg))167                 OnCompleted(g_TcpSocket, arg);168         }169         #endregion170 171         #region 是否已连接172 173         private bool CheckSockectIsConnected(Socket socket)174         {175             lock (g_CloseAsyncLock)176             {177                 if (p_ClosedOver)178                     return false;179                 bool bs = socket.Blocking;180                 socket.Blocking = false;181                 try182                 {183                     socket.Send(StateSendBytes, 0, SocketFlags.None);184                 }185                 catch (SocketException e)186                 {187                     // 10035 == WSAEWOULDBLOCK188                     if (!e.NativeErrorCode.Equals(10035))189                         return false;190                 }191                 finally192                 {193                     socket.Blocking = bs;194                 }195                 return socket.Connected;196             }197         }198 199         private bool CheckSockectIsConnected()200         {201             if (g_TcpSocket != null)202                 return CheckSockectIsConnected(g_TcpSocket);203             else204                 return false;205         }206 207         #endregion208 209         #region ITranseInterfaceTranse 成员210 211         private bool p_ClosedOver = false;212 213         private object g_CloseAsyncLock = new object();214 215         private void CloseCore(bool settonull)216         {217             lock (g_CloseAsyncLock)218             {219                 if (p_ClosedOver) return;220                 p_ClosedOver = true;221                 if (g_TcpSocket != null)222                 {223                     try224                     {225                         g_TcpSocket.Shutdown(SocketShutdown.Both);226                     }227                     catch { }228                     try229                     {230                         g_TcpSocket.Close();231                     }232                     catch { }233                     //if (settonull)234 //    g_TcpSocket = null;235                 }236             }237         }238 239         public void TranseData(ITranseParamets transeparamets)240         {241             if (transeparamets.IsAsyncTranse)242             {243                 switch (transeparamets.DataTranseDirection)244                 {245                     case DataTranseDirection.Connecting:246                         {247                             AsyncConnectToRemoteCore(transeparamets);248                             break;249                         }250                     case DataTranseDirection.SendingData:251                         {252                             AsyncSendDataCore(transeparamets);253                             break;254                         }255                     case DataTranseDirection.ReceivingData:256                         {257                             AsyncRecevDataCore(transeparamets);258                             break;259                         }260                 }261             }262             else263             {264                 switch (transeparamets.DataTranseDirection)265                 {266                     case DataTranseDirection.Connecting:267                         {268                             ConnectToRemoteCore(transeparamets.ConnectToEndPoint,269                                 transeparamets.ConnectTranseInterfaceSetting as TcpIPSocketSetting);270                             break;271                         }272                     case DataTranseDirection.SendingData:273                         {274                             SendDataCore(transeparamets);275                             break;276                         }277                     case DataTranseDirection.ReceivingData:278                         {279                             ReceiveDataCore(transeparamets);280                             break;281                         }282                 }283             }284         }285 286         public void Close()287         {288             CloseCore(true);289         }290 291         public bool IsConnected292         {293             get { return CheckSockectIsConnected(); }294         }295 296         public void WaitClose(object state, WaitCloseDelegate callback)297         {298             try299             {300                 WaitCloseCore(state, callback);301             }302             catch303             {304                 CloseCore(false);305                 if (callback != null)306                     callback(state);307                 //g_TcpSocket = null;308             }309         }310         #endregion311 312         public override string ToString()313         {314             string x = ProtocolTypeName;315             x += "{";316             x += TranseDirection.ToString() + ";";317             Socket s = g_TcpSocket;318             if (s != null)319             {320                 if (s.LocalEndPoint != null)321                     x += s.LocalEndPoint.ToString();322                 if (s.RemoteEndPoint != null)323                     x += "->" + s.RemoteEndPoint.ToString();324             }325             else326                 x += "socket is null";327             x += "}";328             return x;329         }330     }331 332 }

 

interface
  1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5 using System.Net.Sockets;  6 using System.IO;  7 using System.Net;  8   9 namespace YZKStdLibrary.Network.Transe 10 { 11     public interface ITranseParamets 12     { 13         /// <summary> 14 /// 传输头 15 /// </summary> 16         ITranseHeader TranseHeader { get; } 17         /// <summary> 18 /// 传输流 19 /// </summary> 20         Stream TranseStream { get; } 21         /// <summary> 22 /// 传输缓冲区 23 /// </summary> 24         byte[] TranseBuffer { get; } 25         /// <summary> 26 /// 传输缓冲区的偏移量 27 /// </summary> 28         int TranseBufferOffset { get; } 29         /// <summary> 30 /// 传输缓冲区从TranseBufferOffset开始的大小 31 /// </summary> 32         int TranseBufferSize { get; } 33         /// <summary> 34 /// 已传输字节数 35 /// </summary> 36         long BytesTransferred { get; set; } 37         /// <summary> 38 /// 是否是异步传输 39 /// </summary> 40         bool IsAsyncTranse { get; } 41         /// <summary> 42 /// 传输方向 43 /// </summary> 44         DataTranseDirection DataTranseDirection { get; } 45         /// <summary> 46 /// 传输错误 47 /// </summary> 48         Exception TranseError { get; set; } 49         /// <summary> 50 /// 是否取消传输 51 /// </summary> 52         bool IsCancel { get; } 53         /// <summary> 54 /// 指示头传输是否已完成 55 /// </summary> 56         bool HeaderTransedOver { get; } 57         /// <summary> 58 /// 当DataTranseDirection=Connecting时使用 59 /// </summary> 60         EndPoint ConnectToEndPoint { get; } 61         /// <summary> 62 /// 当DataTranseDirection=Connecting时使用 63 /// 指示传输接口设置对象 64 /// </summary> 65         object ConnectTranseInterfaceSetting { get; } 66         /// <summary> 67 /// 头传输完成时调用 68 /// 该方法最低实现要将HeaderTransedOver设为True 69 /// </summary> 70         void HeaderTransed(); 71         /// <summary> 72 /// 异步传输完成时调用 73 /// </summary> 74         void AsyncTranseOver(); 75         /// <summary> 76 /// 异步传输进度通知 77 /// </summary> 78         void AsyncNotyTransing(); 79     } 80  81     /// <summary> 82 /// 数据传输头接口 83 /// </summary> 84     public interface ITranseHeader 85     { 86         /// <summary> 87 /// 传输的数据大小(不包含本头的大小)字节数 88 /// </summary> 89         long TranseSize { get; } 90         /// <summary> 91 /// 其它选项 92 /// </summary> 93         int TranseFlags { get; } 94         /// <summary> 95 /// 包含头的数据(不能为null),为一固定已知大小的字节数 96 /// 该数据包含了头的所有信息 97 /// </summary> 98         byte[] Data { get; } 99         /// <summary>100 /// 当Data属性的容发生变化时(如从网络接收完成Data数据内容时)101 /// 改变方会调用该方法以通知本体依据Data属性的内容重设头属性,如TranseSize和TranseFlags属性值102 /// </summary>103         void ResetParametsFromData();104     }105 106 public enum DataTranseDirection107     {108         /// <summary>109 /// 未知110 /// </summary>111         Unkown,112         /// <summary>113 /// 发送数据114 /// </summary>115         SendingData,116         /// <summary>117 /// 接收数据118 /// </summary>119         ReceivingData,120         /// <summary>121 /// 连接122 /// </summary>123         Connecting124     }125 126 public enum TranseInterfaceDirection127     {128         /// <summary>129 /// 客户端,表示是主动连接方130 /// </summary>131         Client,132         /// <summary>133 /// 服务端,表示是接受连接方134 /// </summary>135         Server136     }137 138 public interface ITranseInterfaceInformation139     {140         /// <summary>141 /// 获取本地终结点信息142 /// </summary>143         EndPoint LocalEndPont { get; }144         /// <summary>145 /// 获取远程终结点信息146 /// </summary>147         EndPoint RemoteEndPoint { get; }148         /// <summary>149 /// 获取当前传输接口建立连接时的方向150 /// </summary>151         TranseInterfaceDirection TranseDirection { get; }152         /// <summary>153 /// 获取传输协义名称154 /// </summary>155         string ProtocolTypeName { get; }156     }157 158  public interface ITranseInterfaceTranse159     {160 161         /// <summary>162 /// 数据传输或连接163 /// 发送或接收或连接:ITranseParamets.DataTranseDirection决定164 /// ITranseParamets.IsAsyncTranse决定是同步还是异步操作165 /// 对于异步操作ITranseParamets.AsyncTranseOver会在操作完成时调用166 /// 对于发送和接收操作ITranseParamets.HeaderTransed会在头发送或接收后调用167 /// </summary>168 /// <param name="transeparamets"></param>169         void TranseData(ITranseParamets transeparamets);170 171         /// <summary>172 /// 关闭传输接口173 /// </summary>174         void Close();175 176         /// <summary>177 /// 是否处于已连接状态178 /// </summary>179         bool IsConnected { get; }180 181         /// <summary>182 /// 等待对方关闭183 /// </summary>184 /// <param name="callback"></param>185         void WaitClose(object state, WaitCloseDelegate callback);186     }187 188     public delegate void WaitCloseDelegate(object state);189 190 191 public interface ITranseInterface : ITranseInterfaceTranse, ITranseInterfaceInformation192     {193     }194 195     public class TcpIPSocketSetting196     {197 198         static TcpIPSocketSetting()199         {200             DefaultLingerOption = new LingerOption(true, 30);201         }202 203         public TcpIPSocketSetting()204         {205             p_NoDelay = false;206             p_ReceiveBufferSize = 8192;207             p_SendBufferSize = 8192;208             p_ReceiveTimeout = 60000;209             p_SendTimeout = 10000;210             p_SocketLinger = null;211         }212 213         private static readonly LingerOption DefaultLingerOption;214 215         private bool p_NoDelay;216 217         public bool NoDelay218         {219             get { return p_NoDelay; }220             set { p_NoDelay = value; }221         }222 223         private int p_ReceiveBufferSize;224 225         public int ReceiveBufferSize226         {227             get { return p_ReceiveBufferSize; }228             set { p_ReceiveBufferSize = value; }229         }230 231         private int p_SendBufferSize;232 233         public int SendBufferSize234         {235             get { return p_SendBufferSize; }236             set { p_SendBufferSize = value; }237         }238 239         private int p_ReceiveTimeout;240 241         public int ReceiveTimeout242         {243             get { return p_ReceiveTimeout; }244             set { p_ReceiveTimeout = value; }245         }246 247         private int p_SendTimeout;248 249         public int SendTimeout250         {251             get { return p_SendTimeout; }252             set { p_SendTimeout = value; }253         }254 255         private LingerOption p_SocketLinger;256 257         public LingerOption SocketLinger258         {259             get260             {261                 return p_SocketLinger == null ? DefaultLingerOption : p_SocketLinger;262             }263             set { p_SocketLinger = value; }264         }265 266         public void AppSetting(Socket s)267         {268             if (s != null)269             {270                 if (SocketLinger != null)271                     s.LingerState = SocketLinger;272                 s.NoDelay = NoDelay;273                 s.ReceiveBufferSize = ReceiveBufferSize;274                 s.SendBufferSize = SendBufferSize;275                 s.ReceiveTimeout = ReceiveTimeout;276                 s.SendTimeout = SendTimeout;277             }278         }279 280     }281 282 }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!