C# 对 TCP 客户端的状态封装
TCP客户端连接TCP服务器端有几种应用状态:
- 与服务器的连接已建立
- 与服务器的连接已断开
- 与服务器的连接发生异常
应用程序可按需求合理处理这些逻辑,比如:
- 连接断开后自动重连
- 连接断开后选择备用地址重连
- 所有状态变化上报告警
本文描述的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 客户端的状态封装的更多相关文章
- 在C#中对TCP客户端的状态封装详解
引用地址: https://www.jb51.net/article/35689.htm
- 系统编程-网络-tcp客户端服务器编程模型(续)、连接断开、获取连接状态场景
相关博文: 系统编程-网络-tcp客户端服务器编程模型.socket.htons.inet_ntop等各API详解.使用telnet测试基本服务器功能 接着该上篇博文,咱们继续,首先,为了内容的完整性 ...
- tcp客户端封装
1.头文件 #ifndef TCPCLIENT_H #define TCPCLIENT_H #include <QTcpSocket> class TcpClient : public Q ...
- 29-ESP8266 SDK开发基础入门篇--编写TCP 客户端程序(Lwip RAW模式,非RTOS版,精简入门)
https://www.cnblogs.com/yangfengwu/p/11456667.html 由于上一节的源码长时间以后会自动断开,所以再做这一版非RTOS版的,咱直接用lua源码里面别人写的 ...
- TCP/IP连接状态
1.建立连接协议(三次握手)(1)客户端发送一个带SYN标志的TCP报文到服务器.这是三次握手过程中的报文1.(2) 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN ...
- TCP连接的状态与关闭方式及其对Server与Client的影响
TCP连接的状态与关闭方式及其对Server与Client的影响 1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用. ...
- TCP连接的状态详解以及故障排查
我们通过了解 TCP各个状态 ,可以排除和定位网络或系统故障时大有帮助. 一.TCP状态 LISTENING :侦听来自远方的TCP端口的连接请求 . 首先服务端需要打开一个 socket 进行监听, ...
- 【RL-TCPnet网络教程】第14章 RL-TCPnet之TCP客户端
第14章 RL-TCPnet之TCP客户端 本章节为大家讲解RL-TCPnet的TCP客户端实现,学习本章节前,务必要优先学习第12章TCP传输控制协议基础知识.有了这些基础知识之后,再搞本 ...
- TCP连接的状态与关闭方式,及其对Server与Client的影响
1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用.特定数据包以及超时等,具体状态如下所示: CLOSED:初始状态, ...
随机推荐
- MyBatis(十):Mybatis缓存的重要内容
本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接 https://space.bilibili.com/95256449?spm_id_from=33 ...
- Tcl编成第二天,set与unset
代码如下: #!/usr/bin/tclsh set value "one" puts $value unset value puts $value set表示创建一个变量第一个参 ...
- C++语言实现双向链表
这篇文章是关于利用C++模板的方式实现的双向链表以及双向链表的基本操作,在之前的博文C语言实现双向链表中,已经给大家分析了双向链表的结构,并以图示的方式给大家解释了双向链表的基本操作.本篇文章利用C+ ...
- Thymeleaf+SpringBoot+SpringDataJPA实现的中小医院信息管理系统
项目简介 项目来源于:https://gitee.com/sensay/hisystem 作者介绍 本系统是基于Thymeleaf+SpringBoot+SpringDataJPA实现的的中小医院信息 ...
- Java包机制和Javadoc的使用
1.什么是包机制? 包(package)其实本质上就是一个文件夹,使用包是为了让相同类名的两个类可以使用,也就是操作系统中的文件夹,用来解决重名并且让相同的功能类放在同一个包,使开发更加有条理. 注意 ...
- AJ学IOS 之微博项目实战(5)微博自定义搜索框searchBar
AJ分享,必须精品 一:效果 用UITextField简单定义一个搜索框 二:调用: 调用的代码,很简单,直接init就可以,以后加功能自己添加就行了. - (void)viewDidLoad { [ ...
- 动态规划_01背包_从Dijikstra和Floyd入手,彻底理解01背包
dp一直是短板,现在从最基础的地方开始补 给定背包总容量 M ,n个商品选择,分别有价值vi,占量wi,从中取商品放入背包,令.容量和W=Σwi不超过M,令背包中的价值和V=Σvi最大 然后取法有很多 ...
- JAVA—SQL注入
之前看到的一道java面试题,Statement与PreparedStatement的区别,什么是SQL注入,如何防止SQL注入 前面部分比较好回答 1.PreparedStatement支持动态设置 ...
- 架构师修炼之设计模式 - 策略模式(Strategy) 【Python与C#实现】
程序员,我为你祝福 愿你有一个灿烂的前程 愿你有情人终成眷属 愿你在尘世获得幸福 我只想成为架构师,走遍江湖! 目录 模式定义 模式分类 模式结构 实例(C#与Python版) 优点 缺点 使用场景 ...
- ASE课程总结 by 林建平
设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的辅助用户在阅读英文文献时记忆生词,提高用户的生词量,减少用户的阅读障碍.定义非常清晰,要有查 ...