TCP客户端连接TCP服务器端有几种应用状态:

  1. 与服务器的连接已建立
  2. 与服务器的连接已断开
  3. 与服务器的连接发生异常

应用程序可按需求合理处理这些逻辑,比如:

  1. 连接断开后自动重连
  2. 连接断开后选择备用地址重连
  3. 所有状态变化上报告警

本文描述的TcpClient实现了状态变化的事件通知机制。

  1   /// <summary>
2 /// 异步TCP客户端
3 /// </summary>
4 public class AsyncTcpClient : IDisposable
5 {
6 #region Fields
7
8 private TcpClient tcpClient;
9 private bool disposed = false;
10 private int retries = 0;
11
12 #endregion
13
14 #region Ctors
15
16 /// <summary>
17 /// 异步TCP客户端
18 /// </summary>
19 /// <param name="remoteEP">远端服务器终结点</param>
20 public AsyncTcpClient(IPEndPoint remoteEP)
21 : this(new[] { remoteEP.Address }, remoteEP.Port)
22 {
23 }
24
25 /// <summary>
26 /// 异步TCP客户端
27 /// </summary>
28 /// <param name="remoteEP">远端服务器终结点</param>
29 /// <param name="localEP">本地客户端终结点</param>
30 public AsyncTcpClient(IPEndPoint remoteEP, IPEndPoint localEP)
31 : this(new[] { remoteEP.Address }, remoteEP.Port, localEP)
32 {
33 }
34
35 /// <summary>
36 /// 异步TCP客户端
37 /// </summary>
38 /// <param name="remoteIPAddress">远端服务器IP地址</param>
39 /// <param name="remotePort">远端服务器端口</param>
40 public AsyncTcpClient(IPAddress remoteIPAddress, int remotePort)
41 : this(new[] { remoteIPAddress }, remotePort)
42 {
43 }
44
45 /// <summary>
46 /// 异步TCP客户端
47 /// </summary>
48 /// <param name="remoteIPAddress">远端服务器IP地址</param>
49 /// <param name="remotePort">远端服务器端口</param>
50 /// <param name="localEP">本地客户端终结点</param>
51 public AsyncTcpClient(
52 IPAddress remoteIPAddress, int remotePort, IPEndPoint localEP)
53 : this(new[] { remoteIPAddress }, remotePort, localEP)
54 {
55 }
56
57 /// <summary>
58 /// 异步TCP客户端
59 /// </summary>
60 /// <param name="remoteHostName">远端服务器主机名</param>
61 /// <param name="remotePort">远端服务器端口</param>
62 public AsyncTcpClient(string remoteHostName, int remotePort)
63 : this(Dns.GetHostAddresses(remoteHostName), remotePort)
64 {
65 }
66
67 /// <summary>
68 /// 异步TCP客户端
69 /// </summary>
70 /// <param name="remoteHostName">远端服务器主机名</param>
71 /// <param name="remotePort">远端服务器端口</param>
72 /// <param name="localEP">本地客户端终结点</param>
73 public AsyncTcpClient(
74 string remoteHostName, int remotePort, IPEndPoint localEP)
75 : this(Dns.GetHostAddresses(remoteHostName), remotePort, localEP)
76 {
77 }
78
79 /// <summary>
80 /// 异步TCP客户端
81 /// </summary>
82 /// <param name="remoteIPAddresses">远端服务器IP地址列表</param>
83 /// <param name="remotePort">远端服务器端口</param>
84 public AsyncTcpClient(IPAddress[] remoteIPAddresses, int remotePort)
85 : this(remoteIPAddresses, remotePort, null)
86 {
87 }
88
89 /// <summary>
90 /// 异步TCP客户端
91 /// </summary>
92 /// <param name="remoteIPAddresses">远端服务器IP地址列表</param>
93 /// <param name="remotePort">远端服务器端口</param>
94 /// <param name="localEP">本地客户端终结点</param>
95 public AsyncTcpClient(
96 IPAddress[] remoteIPAddresses, int remotePort, IPEndPoint localEP)
97 {
98 this.Addresses = remoteIPAddresses;
99 this.Port = remotePort;
100 this.LocalIPEndPoint = localEP;
101 this.Encoding = Encoding.Default;
102
103 if (this.LocalIPEndPoint != null)
104 {
105 this.tcpClient = new TcpClient(this.LocalIPEndPoint);
106 }
107 else
108 {
109 this.tcpClient = new TcpClient();
110 }
111
112 Retries = 3;
113 RetryInterval = 5;
114 }
115
116 #endregion
117
118 #region Properties
119
120 /// <summary>
121 /// 是否已与服务器建立连接
122 /// </summary>
123 public bool Connected { get { return tcpClient.Client.Connected; } }
124 /// <summary>
125 /// 远端服务器的IP地址列表
126 /// </summary>
127 public IPAddress[] Addresses { get; private set; }
128 /// <summary>
129 /// 远端服务器的端口
130 /// </summary>
131 public int Port { get; private set; }
132 /// <summary>
133 /// 连接重试次数
134 /// </summary>
135 public int Retries { get; set; }
136 /// <summary>
137 /// 连接重试间隔
138 /// </summary>
139 public int RetryInterval { get; set; }
140 /// <summary>
141 /// 远端服务器终结点
142 /// </summary>
143 public IPEndPoint RemoteIPEndPoint
144 {
145 get { return new IPEndPoint(Addresses[0], Port); }
146 }
147 /// <summary>
148 /// 本地客户端终结点
149 /// </summary>
150 protected IPEndPoint LocalIPEndPoint { get; private set; }
151 /// <summary>
152 /// 通信所使用的编码
153 /// </summary>
154 public Encoding Encoding { get; set; }
155
156 #endregion
157
158 #region Connect
159
160 /// <summary>
161 /// 连接到服务器
162 /// </summary>
163 /// <returns>异步TCP客户端</returns>
164 public AsyncTcpClient Connect()
165 {
166 if (!Connected)
167 {
168 // start the async connect operation
169 tcpClient.BeginConnect(
170 Addresses, Port, HandleTcpServerConnected, tcpClient);
171 }
172
173 return this;
174 }
175
176 /// <summary>
177 /// 关闭与服务器的连接
178 /// </summary>
179 /// <returns>异步TCP客户端</returns>
180 public AsyncTcpClient Close()
181 {
182 if (Connected)
183 {
184 retries = 0;
185 tcpClient.Close();
186 RaiseServerDisconnected(Addresses, Port);
187 }
188
189 return this;
190 }
191
192 #endregion
193
194 #region Receive
195
196 private void HandleTcpServerConnected(IAsyncResult ar)
197 {
198 try
199 {
200 tcpClient.EndConnect(ar);
201 RaiseServerConnected(Addresses, Port);
202 retries = 0;
203 }
204 catch (Exception ex)
205 {
206 ExceptionHandler.Handle(ex);
207 if (retries > 0)
208 {
209 Logger.Debug(string.Format(CultureInfo.InvariantCulture,
210 "Connect to server with retry {0} failed.", retries));
211 }
212
213 retries++;
214 if (retries > Retries)
215 {
216 // we have failed to connect to all the IP Addresses,
217 // connection has failed overall.
218 RaiseServerExceptionOccurred(Addresses, Port, ex);
219 return;
220 }
221 else
222 {
223 Logger.Debug(string.Format(CultureInfo.InvariantCulture,
224 "Waiting {0} seconds before retrying to connect to server.",
225 RetryInterval));
226 Thread.Sleep(TimeSpan.FromSeconds(RetryInterval));
227 Connect();
228 return;
229 }
230 }
231
232 // we are connected successfully and start asyn read operation.
233 byte[] buffer = new byte[tcpClient.ReceiveBufferSize];
234 tcpClient.GetStream().BeginRead(
235 buffer, 0, buffer.Length, HandleDatagramReceived, buffer);
236 }
237
238 private void HandleDatagramReceived(IAsyncResult ar)
239 {
240 NetworkStream stream = tcpClient.GetStream();
241
242 int numberOfReadBytes = 0;
243 try
244 {
245 numberOfReadBytes = stream.EndRead(ar);
246 }
247 catch
248 {
249 numberOfReadBytes = 0;
250 }
251
252 if (numberOfReadBytes == 0)
253 {
254 // connection has been closed
255 Close();
256 return;
257 }
258
259 // received byte and trigger event notification
260 byte[] buffer = (byte[])ar.AsyncState;
261 byte[] receivedBytes = new byte[numberOfReadBytes];
262 Buffer.BlockCopy(buffer, 0, receivedBytes, 0, numberOfReadBytes);
263 RaiseDatagramReceived(tcpClient, receivedBytes);
264 RaisePlaintextReceived(tcpClient, receivedBytes);
265
266 // then start reading from the network again
267 stream.BeginRead(
268 buffer, 0, buffer.Length, HandleDatagramReceived, buffer);
269 }
270
271 #endregion
272
273 #region Events
274
275 /// <summary>
276 /// 接收到数据报文事件
277 /// </summary>
278 public event EventHandler<TcpDatagramReceivedEventArgs<byte[]>> DatagramReceived;
279 /// <summary>
280 /// 接收到数据报文明文事件
281 /// </summary>
282 public event EventHandler<TcpDatagramReceivedEventArgs<string>> PlaintextReceived;
283
284 private void RaiseDatagramReceived(TcpClient sender, byte[] datagram)
285 {
286 if (DatagramReceived != null)
287 {
288 DatagramReceived(this,
289 new TcpDatagramReceivedEventArgs<byte[]>(sender, datagram));
290 }
291 }
292
293 private void RaisePlaintextReceived(TcpClient sender, byte[] datagram)
294 {
295 if (PlaintextReceived != null)
296 {
297 PlaintextReceived(this,
298 new TcpDatagramReceivedEventArgs<string>(
299 sender, this.Encoding.GetString(datagram, 0, datagram.Length)));
300 }
301 }
302
303 /// <summary>
304 /// 与服务器的连接已建立事件
305 /// </summary>
306 public event EventHandler<TcpServerConnectedEventArgs> ServerConnected;
307 /// <summary>
308 /// 与服务器的连接已断开事件
309 /// </summary>
310 public event EventHandler<TcpServerDisconnectedEventArgs> ServerDisconnected;
311 /// <summary>
312 /// 与服务器的连接发生异常事件
313 /// </summary>
314 public event EventHandler<TcpServerExceptionOccurredEventArgs> ServerExceptionOccurred;
315
316 private void RaiseServerConnected(IPAddress[] ipAddresses, int port)
317 {
318 if (ServerConnected != null)
319 {
320 ServerConnected(this,
321 new TcpServerConnectedEventArgs(ipAddresses, port));
322 }
323 }
324
325 private void RaiseServerDisconnected(IPAddress[] ipAddresses, int port)
326 {
327 if (ServerDisconnected != null)
328 {
329 ServerDisconnected(this,
330 new TcpServerDisconnectedEventArgs(ipAddresses, port));
331 }
332 }
333
334 private void RaiseServerExceptionOccurred(
335 IPAddress[] ipAddresses, int port, Exception innerException)
336 {
337 if (ServerExceptionOccurred != null)
338 {
339 ServerExceptionOccurred(this,
340 new TcpServerExceptionOccurredEventArgs(
341 ipAddresses, port, innerException));
342 }
343 }
344
345 #endregion
346
347 #region Send
348
349 /// <summary>
350 /// 发送报文
351 /// </summary>
352 /// <param name="datagram">报文</param>
353 public void Send(byte[] datagram)
354 {
355 if (datagram == null)
356 throw new ArgumentNullException("datagram");
357
358 if (!Connected)
359 {
360 RaiseServerDisconnected(Addresses, Port);
361 throw new InvalidProgramException(
362 "This client has not connected to server.");
363 }
364
365 tcpClient.GetStream().BeginWrite(
366 datagram, 0, datagram.Length, HandleDatagramWritten, tcpClient);
367 }
368
369 private void HandleDatagramWritten(IAsyncResult ar)
370 {
371 ((TcpClient)ar.AsyncState).GetStream().EndWrite(ar);
372 }
373
374 /// <summary>
375 /// 发送报文
376 /// </summary>
377 /// <param name="datagram">报文</param>
378 public void Send(string datagram)
379 {
380 Send(this.Encoding.GetBytes(datagram));
381 }
382
383 #endregion
384
385 #region IDisposable Members
386
387 /// <summary>
388 /// Performs application-defined tasks associated with freeing,
389 /// releasing, or resetting unmanaged resources.
390 /// </summary>
391 public void Dispose()
392 {
393 Dispose(true);
394 GC.SuppressFinalize(this);
395 }
396
397 /// <summary>
398 /// Releases unmanaged and - optionally - managed resources
399 /// </summary>
400 /// <param name="disposing"><c>true</c> to release both managed
401 /// and unmanaged resources; <c>false</c>
402 /// to release only unmanaged resources.
403 /// </param>
404 protected virtual void Dispose(bool disposing)
405 {
406 if (!this.disposed)
407 {
408 if (disposing)
409 {
410 try
411 {
412 Close();
413
414 if (tcpClient != null)
415 {
416 tcpClient = null;
417 }
418 }
419 catch (SocketException ex)
420 {
421 ExceptionHandler.Handle(ex);
422 }
423 }
424
425 disposed = true;
426 }
427 }
428
429 #endregion
430 }

使用举例

 1   class Program
2 {
3 static AsyncTcpClient client;
4
5 static void Main(string[] args)
6 {
7 LogFactory.Assign(new ConsoleLogFactory());
8
9 // 测试用,可以不指定由系统选择端口
10 IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);
11 IPEndPoint localEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9998);
12 client = new AsyncTcpClient(remoteEP, localEP);
13 client.Encoding = Encoding.UTF8;
14 client.ServerExceptionOccurred +=
15 new EventHandler<TcpServerExceptionOccurredEventArgs>(client_ServerExceptionOccurred);
16 client.ServerConnected +=
17 new EventHandler<TcpServerConnectedEventArgs>(client_ServerConnected);
18 client.ServerDisconnected +=
19 new EventHandler<TcpServerDisconnectedEventArgs>(client_ServerDisconnected);
20 client.PlaintextReceived +=
21 new EventHandler<TcpDatagramReceivedEventArgs<string>>(client_PlaintextReceived);
22 client.Connect();
23
24 Console.WriteLine("TCP client has connected to server.");
25 Console.WriteLine("Type something to send to server...");
26 while (true)
27 {
28 try
29 {
30 string text = Console.ReadLine();
31 client.Send(text);
32 }
33 catch (Exception ex)
34 {
35 Console.WriteLine(ex.Message);
36 }
37 }
38 }
39
40 static void client_ServerExceptionOccurred(
41 object sender, TcpServerExceptionOccurredEventArgs e)
42 {
43 Logger.Debug(string.Format(CultureInfo.InvariantCulture,
44 "TCP server {0} exception occurred, {1}.",
45 e.ToString(), e.Exception.Message));
46 }
47
48 static void client_ServerConnected(
49 object sender, TcpServerConnectedEventArgs e)
50 {
51 Logger.Debug(string.Format(CultureInfo.InvariantCulture,
52 "TCP server {0} has connected.", e.ToString()));
53 }
54
55 static void client_ServerDisconnected(
56 object sender, TcpServerDisconnectedEventArgs e)
57 {
58 Logger.Debug(string.Format(CultureInfo.InvariantCulture,
59 "TCP server {0} has disconnected.", e.ToString()));
60 }
61
62 static void client_PlaintextReceived(
63 object sender, TcpDatagramReceivedEventArgs<string> e)
64 {
65 Console.Write(string.Format("Server : {0} --> ",
66 e.TcpClient.Client.RemoteEndPoint.ToString()));
67 Console.WriteLine(string.Format("{0}", e.Datagram));
68 }
69 }

TCP客户端State

 1   /// <summary>
2 /// Internal class to join the TCP client and buffer together
3 /// for easy management in the server
4 /// </summary>
5 internal class TcpClientState
6 {
7 /// <summary>
8 /// Constructor for a new Client
9 /// </summary>
10 /// <param name="tcpClient">The TCP client</param>
11 /// <param name="buffer">The byte array buffer</param>
12 public TcpClientState(TcpClient tcpClient, byte[] buffer)
13 {
14 if (tcpClient == null)
15 throw new ArgumentNullException("tcpClient");
16 if (buffer == null)
17 throw new ArgumentNullException("buffer");
18
19 this.TcpClient = tcpClient;
20 this.Buffer = buffer;
21 }
22
23 /// <summary>
24 /// Gets the TCP Client
25 /// </summary>
26 public TcpClient TcpClient { get; private set; }
27
28 /// <summary>
29 /// Gets the Buffer.
30 /// </summary>
31 public byte[] Buffer { get; private set; }
32
33 /// <summary>
34 /// Gets the network stream
35 /// </summary>
36 public NetworkStream NetworkStream
37 {
38 get { return TcpClient.GetStream(); }
39 }
40 }

与客户端的连接已建立事件参数

 1   /// <summary>
2 /// 与客户端的连接已建立事件参数
3 /// </summary>
4 public class TcpClientConnectedEventArgs : EventArgs
5 {
6 /// <summary>
7 /// 与客户端的连接已建立事件参数
8 /// </summary>
9 /// <param name="tcpClient">客户端</param>
10 public TcpClientConnectedEventArgs(TcpClient tcpClient)
11 {
12 if (tcpClient == null)
13 throw new ArgumentNullException("tcpClient");
14
15 this.TcpClient = tcpClient;
16 }
17
18 /// <summary>
19 /// 客户端
20 /// </summary>
21 public TcpClient TcpClient { get; private set; }
22 }

与客户端的连接已断开事件参数

  /// <summary>
/// 与客户端的连接已断开事件参数
/// </summary>
public class TcpClientDisconnectedEventArgs : EventArgs
{
/// <summary>
/// 与客户端的连接已断开事件参数
/// </summary>
/// <param name="tcpClient">客户端</param>
public TcpClientDisconnectedEventArgs(TcpClient tcpClient)
{
if (tcpClient == null)
throw new ArgumentNullException("tcpClient"); this.TcpClient = tcpClient;
} /// <summary>
/// 客户端
/// </summary>
public TcpClient TcpClient { get; private set; }
}

与服务器的连接发生异常事件参数

 1   /// <summary>
2 /// 与服务器的连接发生异常事件参数
3 /// </summary>
4 public class TcpServerExceptionOccurredEventArgs : EventArgs
5 {
6 /// <summary>
7 /// 与服务器的连接发生异常事件参数
8 /// </summary>
9 /// <param name="ipAddresses">服务器IP地址列表</param>
10 /// <param name="port">服务器端口</param>
11 /// <param name="innerException">内部异常</param>
12 public TcpServerExceptionOccurredEventArgs(
13 IPAddress[] ipAddresses, int port, Exception innerException)
14 {
15 if (ipAddresses == null)
16 throw new ArgumentNullException("ipAddresses");
17
18 this.Addresses = ipAddresses;
19 this.Port = port;
20 this.Exception = innerException;
21 }
22
23 /// <summary>
24 /// 服务器IP地址列表
25 /// </summary>
26 public IPAddress[] Addresses { get; private set; }
27 /// <summary>
28 /// 服务器端口
29 /// </summary>
30 public int Port { get; private set; }
31 /// <summary>
32 /// 内部异常
33 /// </summary>
34 public Exception Exception { get; private set; }
35
36 /// <summary>
37 /// Returns a <see cref="System.String"/> that represents this instance.
38 /// </summary>
39 /// <returns>
40 /// A <see cref="System.String"/> that represents this instance.
41 /// </returns>
42 public override string ToString()
43 {
44 string s = string.Empty;
45 foreach (var item in Addresses)
46 {
47 s = s + item.ToString() + ',';
48 }
49 s = s.TrimEnd(',');
50 s = s + ":" + Port.ToString(CultureInfo.InvariantCulture);
51
52 return s;
53 }
54 }

接收到数据报文事件参数

 1   /// <summary>
2 /// 接收到数据报文事件参数
3 /// </summary>
4 /// <typeparam name="T">报文类型</typeparam>
5 public class TcpDatagramReceivedEventArgs<T> : EventArgs
6 {
7 /// <summary>
8 /// 接收到数据报文事件参数
9 /// </summary>
10 /// <param name="tcpClient">客户端</param>
11 /// <param name="datagram">报文</param>
12 public TcpDatagramReceivedEventArgs(TcpClient tcpClient, T datagram)
13 {
14 TcpClient = tcpClient;
15 Datagram = datagram;
16 }
17
18 /// <summary>
19 /// 客户端
20 /// </summary>
21 public TcpClient TcpClient { get; private set; }
22 /// <summary>
23 /// 报文
24 /// </summary>
25 public T Datagram { get; private set; }
26 }

与服务器的连接已建立事件参数

 1   /// <summary>
2 /// 与服务器的连接已建立事件参数
3 /// </summary>
4 public class TcpServerConnectedEventArgs : EventArgs
5 {
6 /// <summary>
7 /// 与服务器的连接已建立事件参数
8 /// </summary>
9 /// <param name="ipAddresses">服务器IP地址列表</param>
10 /// <param name="port">服务器端口</param>
11 public TcpServerConnectedEventArgs(IPAddress[] ipAddresses, int port)
12 {
13 if (ipAddresses == null)
14 throw new ArgumentNullException("ipAddresses");
15
16 this.Addresses = ipAddresses;
17 this.Port = port;
18 }
19
20 /// <summary>
21 /// 服务器IP地址列表
22 /// </summary>
23 public IPAddress[] Addresses { get; private set; }
24 /// <summary>
25 /// 服务器端口
26 /// </summary>
27 public int Port { get; private set; }
28
29 /// <summary>
30 /// Returns a <see cref="System.String"/> that represents this instance.
31 /// </summary>
32 /// <returns>
33 /// A <see cref="System.String"/> that represents this instance.
34 /// </returns>
35 public override string ToString()
36 {
37 string s = string.Empty;
38 foreach (var item in Addresses)
39 {
40 s = s + item.ToString() + ',';
41 }
42 s = s.TrimEnd(',');
43 s = s + ":" + Port.ToString(CultureInfo.InvariantCulture);
44
45 return s;
46 }
47 }

与服务器的连接已断开事件参数

 1   /// <summary>
2 /// 与服务器的连接已断开事件参数
3 /// </summary>
4 public class TcpServerDisconnectedEventArgs : EventArgs
5 {
6 /// <summary>
7 /// 与服务器的连接已断开事件参数
8 /// </summary>
9 /// <param name="ipAddresses">服务器IP地址列表</param>
10 /// <param name="port">服务器端口</param>
11 public TcpServerDisconnectedEventArgs(IPAddress[] ipAddresses, int port)
12 {
13 if (ipAddresses == null)
14 throw new ArgumentNullException("ipAddresses");
15
16 this.Addresses = ipAddresses;
17 this.Port = port;
18 }
19
20 /// <summary>
21 /// 服务器IP地址列表
22 /// </summary>
23 public IPAddress[] Addresses { get; private set; }
24 /// <summary>
25 /// 服务器端口
26 /// </summary>
27 public int Port { get; private set; }
28
29 /// <summary>
30 /// Returns a <see cref="System.String"/> that represents this instance.
31 /// </summary>
32 /// <returns>
33 /// A <see cref="System.String"/> that represents this instance.
34 /// </returns>
35 public override string ToString()
36 {
37 string s = string.Empty;
38 foreach (var item in Addresses)
39 {
40 s = s + item.ToString() + ',';
41 }
42 s = s.TrimEnd(',');
43 s = s + ":" + Port.ToString(CultureInfo.InvariantCulture);
44
45 return s;
46 }
47 }

C# 对 TCP 客户端的状态封装的更多相关文章

  1. 在C#中对TCP客户端的状态封装详解

    引用地址: https://www.jb51.net/article/35689.htm

  2. 系统编程-网络-tcp客户端服务器编程模型(续)、连接断开、获取连接状态场景

    相关博文: 系统编程-网络-tcp客户端服务器编程模型.socket.htons.inet_ntop等各API详解.使用telnet测试基本服务器功能 接着该上篇博文,咱们继续,首先,为了内容的完整性 ...

  3. tcp客户端封装

    1.头文件 #ifndef TCPCLIENT_H #define TCPCLIENT_H #include <QTcpSocket> class TcpClient : public Q ...

  4. 29-ESP8266 SDK开发基础入门篇--编写TCP 客户端程序(Lwip RAW模式,非RTOS版,精简入门)

    https://www.cnblogs.com/yangfengwu/p/11456667.html 由于上一节的源码长时间以后会自动断开,所以再做这一版非RTOS版的,咱直接用lua源码里面别人写的 ...

  5. TCP/IP连接状态

    1.建立连接协议(三次握手)(1)客户端发送一个带SYN标志的TCP报文到服务器.这是三次握手过程中的报文1.(2) 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN ...

  6. TCP连接的状态与关闭方式及其对Server与Client的影响

    TCP连接的状态与关闭方式及其对Server与Client的影响 1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用. ...

  7. TCP连接的状态详解以及故障排查

    我们通过了解 TCP各个状态 ,可以排除和定位网络或系统故障时大有帮助. 一.TCP状态 LISTENING :侦听来自远方的TCP端口的连接请求 . 首先服务端需要打开一个 socket 进行监听, ...

  8. 【RL-TCPnet网络教程】第14章 RL-TCPnet之TCP客户端

    第14章      RL-TCPnet之TCP客户端 本章节为大家讲解RL-TCPnet的TCP客户端实现,学习本章节前,务必要优先学习第12章TCP传输控制协议基础知识.有了这些基础知识之后,再搞本 ...

  9. TCP连接的状态与关闭方式,及其对Server与Client的影响

    1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用.特定数据包以及超时等,具体状态如下所示: CLOSED:初始状态, ...

随机推荐

  1. webpack4.0(01.基础配置和初识)

    1.什么是webpack? 2.webpack可以做什莫? 代码转换.文件优化.代码分割.模块合并.自动刷新.代码校验.自动发布 3.我们要学习webpack的什么? 4.使用webpack 1.首先 ...

  2. Django模拟ASP.NET MVC 自动匹配路由(转载)

    项目结构 操作步骤 1.创建项目结构如上图 2.在myapp目录下创建urls文件,代码: from django.conf.urls import patterns, url from untitl ...

  3. Python设计模式(3)-工厂方法模式

    # coding=utf-8 #定义一个用于创建对象的接口,让子类决定实例化哪一个类 class DbManager: def __init__(self): pass def operate_db( ...

  4. python-从酷狗下载爬取自己想要的音乐-可以直接拿来体验哟

    因为最近发现咪咕音乐版权好多,当时我就在想是不是可以爬取下来,然后花了一些时间,发现有加密,虽然找到了接口,但是只能手动下载VIP歌曲,对于我们学IT的人来说,这是不能忍的,于是就懒得去解密抓取了,但 ...

  5. 搭建WEB、NFS共享、sersync实时同步以及全网定时备份服务流程

    本次实验的主要目的: 1.搭建web服务,使用nfs服务共享的/data目录挂载到web站点目录上. 2.nfs服务器与backup服务器使用sersync实时同步/data目录中的文件. 3.bac ...

  6. hibernate.current_session_context_class 比较权威的解释

    hibernate.current_session_context_class 博客分类: hibernate HibernateSpring多线程配置管理thread  遇到过的问题: 情景1: 在 ...

  7. 理解class.forName() ---使用jdbc方式链接数据库时会经常看到这句代码

    目录(?)[-] 官方文档 类装载 两种装载方法的区别 不同的类装载器 是否实例化类 在jdbc链接数据库中的应用 资源   原文地址:http://yanwushu.sinaapp.com/clas ...

  8. 面试问了解Linux内存管理吗?10张图给你安排的明明白白!

    文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 今天来带大家研究一下Linux内存管理.对于精通 CURD 的业务同学 ...

  9. 把川普射上太阳—如何用python制作小游戏

    1.准备 开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装. Windows环境下打开Cmd(开始—运行—CMD),苹果系统 ...

  10. Java数组 —— 八大排序

    (请观看本人博文--<详解 普通数组 -- Arrays类 与 浅克隆>) 在本人<数据结构与算法>专栏的讲解中,本人讲解了如何去实现数组的八大排序. 但是,在讲解的过程中,我 ...