高性能Socket客户端示例

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Net.Sockets;
  6 using System.Threading;
  7 using System.Net;
  8 
  9 namespace SocketAsyncEventTest
 10 {
 11     class Program
 12     {
 13         static byte[] Buff = new byte[512];
 14         
 15 
 16         static void Main(string[] args)
 17         {
 18             Socket sK = new Socket(AddressFamily.InterNetwork,
 19                 SocketType.Stream,
 20                 ProtocolType.Tcp);
 21 
 22             //建立SocketAsyncEventArgsPool池子,和Buff池子来解决多客户端问题
 23             SocketAsyncEventArgs asyncArgs = new SocketAsyncEventArgs();
 24             asyncArgs.SetBuffer(Buff,
 25                 0,
 26                 Buff.Length);
 27             asyncArgs.Completed+=new EventHandler<SocketAsyncEventArgs>(AsyncArgs_Completed);
 28 
 29             ManualResetEvent connEvent = new ManualResetEvent(false);
 30             asyncArgs.UserToken = connEvent;
 31 
 32             asyncArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.42"), 9999);
 33             if (!sK.ConnectAsync(asyncArgs))
 34             {
 35                 if (sK.Connected)
 36                 {
 37                     asyncArgs.UserToken = sK;
 38                     Console.WriteLine("Connect Success!");
 39                     if (!sK.ReceiveAsync(asyncArgs))
 40                     {
 41                         ProcessReceive(asyncArgs);
 42                     }
 43 
 44                     ThreadPool.QueueUserWorkItem(new WaitCallback(SendCallback), asyncArgs);
 45                 }
 46                 else {
 47                     Console.WriteLine("Connect Faild!");
 48                 }
 49             }
 50             else
 51             {
 52                 if (connEvent.WaitOne(10 * 1000))
 53                 {
 54                     asyncArgs.UserToken = sK;
 55                     Console.WriteLine("Connect Success!");
 56 
 57                     if (!sK.ReceiveAsync(asyncArgs))
 58                     {
 59                         ProcessReceive(asyncArgs);
 60                     }
 61 
 62                     ThreadPool.QueueUserWorkItem(new WaitCallback(SendCallback), sK);
 63                 }
 64                 else
 65                 {
 66                     Console.WriteLine("Connect Timeout!");
 67                 }
 68             }
 69            
 70             connEvent.Close();
 71             Console.ReadKey(false);
 72         }
 73 
 74         static void AsyncArgs_Completed(object sender, SocketAsyncEventArgs e)
 75         {
 76             if (e.SocketError == SocketError.Success)
 77             {
 78                 switch (e.LastOperation)
 79                 {
 80                     case SocketAsyncOperation.Connect:
 81                         ManualResetEvent connEvent = e.UserToken as ManualResetEvent;
 82                         if (connEvent != null)
 83                         {
 84                             connEvent.Set();
 85                         }
 86                         break;
 87                     case SocketAsyncOperation.Receive:
 88                         ProcessReceive(e);
 89                         break;
 90                 }
 91             }
 92             else
 93             {
 94                 //SafeShutdown,  并把SocketAsyncEventArgs 放回池子里
 95             }
 96         }
 97 
 98         static void ProcessReceive(SocketAsyncEventArgs args)
 99         {
100             /*
101              * 如何避免被放回池子的对象还在原来的Socket中继续Receive呢,
102              * 这里就需要判断一下状态咯
103              */
104             if (args.SocketError == SocketError.Success)
105             {
106                 if (args.BytesTransferred > 0)
107                 {
108                     byte[] buff = new byte[args.BytesTransferred];
109                     Buffer.BlockCopy(args.Buffer,
110                         args.Offset,
111                         buff,
112                         0,
113                         buff.Length);
114                     Console.WriteLine("Receive:{0}", Encoding.UTF8.GetString(buff));
115                 }
116                 Socket sK = args.UserToken as Socket;
117                 if (sK != null)
118                 {
119                     if (!sK.ReceiveAsync(args))
120                     {
121                         ProcessReceive(args);
122                     }
123                 }
124             }
125         }
126 
127         static void ProcessSend(IAsyncResult iar)
128         {
129             Socket sK = (Socket)iar.AsyncState;
130             if (sK.Connected)
131             {
132                 try
133                 {
134                     sK.EndSend(iar);
135                 }
136                 catch (Exception ex)
137                 {
138                     Console.WriteLine(ex.Message);
139 
140                     //SafeShutdown,对于SocketAsyncEventArgs的回收,需要IAsyncResult来传递不同的UserToken
141                 }
142             }
143         }
144 
145         static void SendCallback(object args)
146         {
147             Socket sK = (Socket)args;
148             byte[] buff = Encoding.UTF8.GetBytes("Hello SocketAsyncEventArgs!");
149             while (true)
150             {
151                 if (sK.Connected)
152                 {
153                     sK.BeginSend(buff,
154                         0,
155                         buff.Length,
156                         SocketFlags.None,
157                         new AsyncCallback(ProcessSend),
158                         sK);
159                 }
160                 else
161                 {
162                     break;
163                 }
164                 Thread.Sleep(10);
165             }
166             Console.WriteLine("Stop Send!");
167         }
168     }
169 }
原文地址:https://www.cnblogs.com/cxwx/p/2428933.html