关于socket 的学习
在前一篇讲到了服务侦听,具体构建了一个抽象类,该类是后续服务类中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长度数据等待对方关闭时肯定在回调中引发错误,此时关闭.
以下为代码:
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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.BytesTransferred
101 /// </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.BytesTransferred
119 /// </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 #endregion
135
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 #endregion
199
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 else
279 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 try
293 {
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 try
318 {
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 try
356 {
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 try
374 {
375 bool hd = HandlerReceiver(paramets, e.BytesTransferred);
376 paramets.AsyncNotyTransing();
377 if (hd)
378 {
379 ovcall = true;
380 OverAsyncTranse(e, paramets, null);
381 }
382 else
383 {
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 #endregion
398
399 }
400
401 }
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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 waitCloseParamets
112 {
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 State
124 {
125 get { return state; }
126 }
127
128 public WaitCloseDelegate Callback
129 {
130 get
131 {
132 return callback;
133 }
134 }
135 }
136 #endregion
137
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 #endregion
170
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 try
182 {
183 socket.Send(StateSendBytes, 0, SocketFlags.None);
184 }
185 catch (SocketException e)
186 {
187 // 10035 == WSAEWOULDBLOCK
188 if (!e.NativeErrorCode.Equals(10035))
189 return false;
190 }
191 finally
192 {
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 else
204 return false;
205 }
206
207 #endregion
208
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 try
224 {
225 g_TcpSocket.Shutdown(SocketShutdown.Both);
226 }
227 catch { }
228 try
229 {
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 else
263 {
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 IsConnected
292 {
293 get { return CheckSockectIsConnected(); }
294 }
295
296 public void WaitClose(object state, WaitCloseDelegate callback)
297 {
298 try
299 {
300 WaitCloseCore(state, callback);
301 }
302 catch
303 {
304 CloseCore(false);
305 if (callback != null)
306 callback(state);
307 //g_TcpSocket = null;
308 }
309 }
310 #endregion
311
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 else
326 x += "socket is null";
327 x += "}";
328 return x;
329 }
330 }
331
332 }
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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 DataTranseDirection
107 {
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 Connecting
124 }
125
126 public enum TranseInterfaceDirection
127 {
128 /// <summary>
129 /// 客户端,表示是主动连接方
130 /// </summary>
131 Client,
132 /// <summary>
133 /// 服务端,表示是接受连接方
134 /// </summary>
135 Server
136 }
137
138 public interface ITranseInterfaceInformation
139 {
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 ITranseInterfaceTranse
159 {
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, ITranseInterfaceInformation
192 {
193 }
194
195 public class TcpIPSocketSetting
196 {
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 NoDelay
218 {
219 get { return p_NoDelay; }
220 set { p_NoDelay = value; }
221 }
222
223 private int p_ReceiveBufferSize;
224
225 public int ReceiveBufferSize
226 {
227 get { return p_ReceiveBufferSize; }
228 set { p_ReceiveBufferSize = value; }
229 }
230
231 private int p_SendBufferSize;
232
233 public int SendBufferSize
234 {
235 get { return p_SendBufferSize; }
236 set { p_SendBufferSize = value; }
237 }
238
239 private int p_ReceiveTimeout;
240
241 public int ReceiveTimeout
242 {
243 get { return p_ReceiveTimeout; }
244 set { p_ReceiveTimeout = value; }
245 }
246
247 private int p_SendTimeout;
248
249 public int SendTimeout
250 {
251 get { return p_SendTimeout; }
252 set { p_SendTimeout = value; }
253 }
254
255 private LingerOption p_SocketLinger;
256
257 public LingerOption SocketLinger
258 {
259 get
260 {
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 }