C#异步TCP服务器完整实现

更新时间:2023-05-23 05:51:39 阅读: 评论:0

C#异步TCP服务器完整实现
TCP异步Socket模型
C#的TCP异步Socket模型是通过Begin-End模式实现的。例如提供 BeginConnect、BeginAccept、BeginSend 和 BeginReceive等。IAsyncResult BeginAccept(AsyncCallback callback, object state);
AsyncCallback 回调在函数执⾏完毕后执⾏。state 对象被⽤于在执⾏函数和回调函数间传输信息。
Socket socket = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 8888);
socket.Bind(iep);
socket.Listen(5);
socket.BeginAccept (new AsyncCallback(CallbackAccept), socket);
private void CallbackAccept(IAsyncResult iar)
{
Socket rver = (Socket)iar.AsyncState;
Socket client = rver.EndAccept(iar);
}
则在Accept⼀个TcpClient,需要维护TcpClient列表。
private List<TcpClientState> clients;
异步TCP服务器完整实现
1///<summary>
2///异步TCP服务器
3///</summary>
4public class AsyncTcpServer : IDisposable
5  {
6#region Fields
7
8private TcpListener listener;
9private List<TcpClientState> clients;
10private bool dispod = fal;
11
12#endregion
13
chinanet14#region Ctors
15
16///<summary>
17///异步TCP服务器
18///</summary>
19///<param name="listenPort">监听的端⼝</param>
20public AsyncTcpServer(int listenPort)
21      : this(IPAddress.Any, listenPort)
22    {
23    }
24
25///<summary>
26///异步TCP服务器
27///</summary>
28///<param name="localEP">监听的终结点</param>
29public AsyncTcpServer(IPEndPoint localEP)
30      : this(localEP.Address, localEP.Port)
31    {
32    }
33
34///<summary>
35///异步TCP服务器
36///</summary>
37///<param name="localIPAddress">监听的IP地址</param>
38///<param name="listenPort">监听的端⼝</param>
39public AsyncTcpServer(IPAddress localIPAddress, int listenPort)
40    {
41      Address = localIPAddress;
42      Port = listenPort;
43this.Encoding = Encoding.Default;
44
45      clients = new List<TcpClientState>();
46
47      listener = new TcpListener(Address, Port);
48      listener.AllowNatTraversal(true);
49    }
50
51#endregion
52
53#region Properties
54
55///<summary>
naomi campbell56///服务器是否正在运⾏
57///</summary>
58public bool IsRunning { get; private t; }
59///<summary>
60///监听的IP地址
61///</summary>
61///</summary>
62public IPAddress Address { get; private t; }
63///<summary>
64///监听的端⼝
65///</summary>
66public int Port { get; private t; }
67///<summary>
68///通信使⽤的编码
69///</summary>
70public Encoding Encoding { get; t; }
71
72#endregion
73
74#region Server
75
76///<summary>
77///启动服务器
78///</summary>
79///<returns>异步TCP服务器</returns>
80public AsyncTcpServer Start()
81    {
82if (!IsRunning)
83      {
84        IsRunning = true;
85        listener.Start();
86        listener.BeginAcceptTcpClient(
87new AsyncCallback(HandleTcpClientAccepted), listener);
88      }
89return this;
90    }
91
92///<summary>
93///启动服务器
94///</summary>
95///<param name="backlog">
96///服务器所允许的挂起连接序列的最⼤长度
97///</param>
98///<returns>异步TCP服务器</returns>
99public AsyncTcpServer Start(int backlog)
100    {
101if (!IsRunning)
102      {
103        IsRunning = true;
104        listener.Start(backlog);
105        listener.BeginAcceptTcpClient(
106new AsyncCallback(HandleTcpClientAccepted), listener); 107      }
108return this;
109    }
110
111///<summary>
112///停⽌服务器
113///</summary>
114///<returns>异步TCP服务器</returns>
115public AsyncTcpServer Stop()
116    {
117if (IsRunning)
118      {
119        IsRunning = fal;
120        listener.Stop();
121
122lock (this.clients)
123        {
124for (int i = 0; i < this.clients.Count; i++)
125          {
126this.clients[i].TcpClient.Client.Disconnect(fal);
127          }
128this.clients.Clear();
129        }
130
131      }
132return this;
133    }
134
135#endregion
136
137#region Receive
138
139private void HandleTcpClientAccepted(IAsyncResult ar) 140    {
141if (IsRunning)
142      {
143        TcpListener tcpListener = (TcpListener)ar.AsyncState; 144
145        TcpClient tcpClient = tcpListener.EndAcceptTcpClient(ar);
145        TcpClient tcpClient = tcpListener.EndAcceptTcpClient(ar);
146byte[] buffer = new byte[tcpClient.ReceiveBufferSize];
147
148        TcpClientState internalClient
149          = new TcpClientState(tcpClient, buffer);
150lock (this.clients)
151        {
152this.clients.Add(internalClient);
153          RaiClientConnected(tcpClient);
154        }
155
156        NetworkStream networkStream = internalClient.NetworkStream;
157        networkStream.BeginRead(
158          internalClient.Buffer,
1590,
160          internalClient.Buffer.Length,
161          HandleDatagramReceived,
162          internalClient);
163
164        tcpListener.BeginAcceptTcpClient(
165new AsyncCallback(HandleTcpClientAccepted), ar.AsyncState);
166      }
167    }
168
169private void HandleDatagramReceived(IAsyncResult ar)
170    {
171if (IsRunning)
172      {
173        TcpClientState internalClient = (TcpClientState)ar.AsyncState;
174        NetworkStream networkStream = internalClient.NetworkStream;
175
176int numberOfReadBytes = 0;
177try
178        {
179          numberOfReadBytes = networkStream.EndRead(ar);
180        }
181catch
182        {
183          numberOfReadBytes = 0;
184        }
185
186if (numberOfReadBytes == 0)
187        {
188// connection has been clod
189lock (this.clients)
190          {
191this.clients.Remove(internalClient);
192            RaiClientDisconnected(internalClient.TcpClient);
193return;
194          }
195        }
196
197// received byte and trigger event notification
198byte[] receivedBytes = new byte[numberOfReadBytes];
199        Buffer.BlockCopy(
200          internalClient.Buffer, 0,
201          receivedBytes, 0, numberOfReadBytes);
202        RaiDatagramReceived(internalClient.TcpClient, receivedBytes);
203        RaiPlaintextReceived(internalClient.TcpClient, receivedBytes);
204
205// continue listening for tcp datagram packets
206        networkStream.BeginRead(
207          internalClient.Buffer,
2080,
209          internalClient.Buffer.Length,
210          HandleDatagramReceived,
211          internalClient);
212      }
213    }
214
215#endregion
vagueness216
217#region Events
218
219///<summary>
220///接收到数据报⽂事件
221///</summary>
222public event EventHandler<TcpDatagramReceivedEventArgs<byte[]>> DatagramReceived; 223///<summary>
224///接收到数据报⽂明⽂事件
225///</summary>
226public event EventHandler<TcpDatagramReceivedEventArgs<string>> PlaintextReceived; 227
228private void RaiDatagramReceived(TcpClient nder, byte[] datagram)
229    {
230if (DatagramReceived != null)
230if (DatagramReceived != null)
231      {
232        DatagramReceived(this, new TcpDatagramReceivedEventArgs<byte[]>(nder, datagram)); 233      }
234    }
235
236private void RaiPlaintextReceived(TcpClient nder, byte[] datagram)
237    {
238if (PlaintextReceived != null)
239      {
240        PlaintextReceived(this, new TcpDatagramReceivedEventArgs<string>(
241          nder, this.Encoding.GetString(datagram, 0, datagram.Length)));
242      }
243    }
244
245///<summary>
246///与客户端的连接已建⽴事件
247///</summary>
248public event EventHandler<TcpClientConnectedEventArgs> ClientConnected;
249///<summary>
250///与客户端的连接已断开事件
251///</summary>
252public event EventHandler<TcpClientDisconnectedEventArgs> ClientDisconnected;
253
254private void RaiClientConnected(TcpClient tcpClient)
255    {
256if (ClientConnected != null)
257      {
258        ClientConnected(this, new TcpClientConnectedEventArgs(tcpClient));
259      }
260    }
261
262private void RaiClientDisconnected(TcpClient tcpClient)
263    {
264if (ClientDisconnected != null)
265      {
266        ClientDisconnected(this, new TcpClientDisconnectedEventArgs(tcpClient));
267      }
268    }
269
270#endregion
271
272#region Send
273
274///<summary>
275///发送报⽂⾄指定的客户端
276///</summary>
277///<param name="tcpClient">客户端</param>
i do 电影278///<param name="datagram">报⽂</param>
279public void Send(TcpClient tcpClient, byte[] datagram)
280    {
281if (!IsRunning)
282throw new InvalidProgramException("This TCP rver has not been started.");
283
284if (tcpClient == null)
285throw new ArgumentNullException("tcpClient");
286
287if (datagram == null)
288throw new ArgumentNullException("datagram");
289
ecci
290      tcpClient.GetStream().BeginWrite(
291        datagram, 0, datagram.Length, HandleDatagramWritten, tcpClient);
292    }
293
294private void HandleDatagramWritten(IAsyncResult ar)
295    {
296      ((TcpClient)ar.AsyncState).GetStream().EndWrite(ar);
297    }
298
299///<summary>
300///发送报⽂⾄指定的客户端
301///</summary>
302///<param name="tcpClient">客户端</param>
303///<param name="datagram">报⽂</param>
304public void Send(TcpClient tcpClient, string datagram)
305    {
306      Send(tcpClient, this.Encoding.GetBytes(datagram));
307    }
308
309///<summary>
310///发送报⽂⾄所有客户端
311///</summary>
312///<param name="datagram">报⽂</param>
313public void SendAll(byte[] datagram)
314    {
314    {
315if (!IsRunning)
316throw new InvalidProgramException("This TCP rver has not been started."); 317
318for (int i = 0; i < this.clients.Count; i++)
319      {
320        Send(this.clients[i].TcpClient, datagram);
321      }
322    }
323
324///<summary>
325///发送报⽂⾄所有客户端
326///</summary>
327///<param name="datagram">报⽂</param>
328public void SendAll(string datagram)
329    {
330if (!IsRunning)
331throw new InvalidProgramException("This TCP rver has not been started."); 332
333      SendAll(this.Encoding.GetBytes(datagram));
334    }
335
336#endregion
337
338#region IDisposable Members
339
340///<summary>
341/// Performs application-defined tasks associated with freeing,
342/// releasing, or retting unmanaged resources.
343///</summary>
344public void Dispo()
345    {
346      Dispo(true);
347      GC.SuppressFinalize(this);
348    }
349
350///<summary>
351/// Releas unmanaged and - optionally - managed resources
352///</summary>
353///<param name="disposing"><c>true</c> to relea
354/// both managed and unmanaged resources; <c>fal</c>
355/// to relea only unmanaged resources.</param>
356protected virtual void Dispo(bool disposing)
357    {
358if (!this.dispod)
359      {
360if (disposing)
361        {
362try
363          {
364            Stop();
365
366if (listener != null)
367            {
368              listener = null;
369            }
370          }
371catch (SocketException ex)
372          {
373            ExceptionHandler.Handle(ex);
374          }
375        }
烟台家教
376
377        dispod = true;
378      }
379    }
380
381#endregion
382  }
overall是什么意思使⽤举例
1class Program
等一下韩语
2  {
3static AsyncTcpServer rver;
4
5static void Main(string[] args)
6    {
7      LogFactory.Assign(new ConsoleLogFactory());
8
9      rver = new AsyncTcpServer(9999);
10      rver.Encoding = Encoding.UTF8;
11      rver.ClientConnected +=
12new EventHandler<TcpClientConnectedEventArgs>(rver_ClientConnected);
13      rver.ClientDisconnected +=
英语机构加盟
manchester14new EventHandler<TcpClientDisconnectedEventArgs>(rver_ClientDisconnected);
15      rver.PlaintextReceived +=

本文发布于:2023-05-23 05:51:39,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/741421.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:服务器   连接   函数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图