高性能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 }
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 }