[转自
听香水榭]
一个封装的异步Socket客户端
1
using System;
2
using System.Collections;
3
using System.Configuration;
4
using System.Net;
5
using System.Net.Sockets;
6
using System.Text;
7
8
namespace Beijing.Traffic.Mobile.Net
9

{
10
/**//**//**//// <summary>
11
/// 智能手机端网络访问类
12
/// </summary>
13
public class MobileClient
14
{
15
//服务器IP地址
16
private string serverIP;
17
//服务器访问端口
18
private string serverPort;
19
private Socket socket;
20
private byte [] buffer = new byte[256];
21
private StringBuilder receiveData = null;
22
private SocketEventArgs socketEventArgs = null;
23
24
事件事件#region 事件
25
//连接完成事件
26
public event EventHandler OnConnect;
27
//接收完成事件
28
public event EventHandler OnReceivedFinshed;
29
//发送数据成功
30
public event EventHandler OnSendFinished;
31
//产生异常时调用此事件
32
public event EventHandler OnException;
33
34
#endregion
35
36
构造函数构造函数#region 构造函数
37
38
public MobileClient()
39
{
40
this.serverIP = ConfigurationSettings.AppSettings["ServerIP"];
41
this.serverPort = ConfigurationSettings.AppSettings["ServerPort"];
42
receiveData = new StringBuilder();
43
}
44
public MobileClient(string ip,string port)
45
{
46
this.serverIP = ip;
47
this.serverPort = port;
48
receiveData = new StringBuilder();
49
50
}
51
#endregion
52
53
private void UpdateEventMessage(string msg)
54
{
55
if( socketEventArgs == null)
56
{
57
socketEventArgs = new SocketEventArgs();
58
socketEventArgs.ServerIP = this.serverIP;
59
socketEventArgs.ServerPort = this.serverPort;
60
}
61
socketEventArgs.Message = msg;
62
63
}
64
65
/**//**//**//// <summary>
66
/// 处理异常的事件
67
/// </summary>
68
/// <param name="msg"></param>
69
private void HandlerException(string msg)
70
{
71
if(OnException != null)
72
{
73
UpdateEventMessage(msg);
74
OnException(this,socketEventArgs);
75
76
}
77
else
78
{
79
throw new Exception("异常处理事件不能为空");
80
}
81
}
82
83
连接远程服务器连接远程服务器#region 连接远程服务器
84
85
86
/**//**//**//// <summary>
87
/// 异步连接远程服务器
88
/// </summary>
89
/// <returns></returns>
90
public void Connect()
91
{
92
try
93
{
94
if( socket != null && socket.Connected )
95
{
96
socket.Shutdown( SocketShutdown.Both );
97
System.Threading.Thread.Sleep( 10 );
98
socket.Close();
99
}
100
socket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
101
102
IPEndPoint epServer = new IPEndPoint(IPAddress.Parse(serverIP),int.Parse(serverPort));
103
104
socket.Blocking = false;
105
socket.BeginConnect( epServer, new AsyncCallback(Connected),socket );
106
}
107
catch(Exception ex)
108
{
109
this.Close();
110
this.HandlerException(ex.Message);
111
}
112
}
113
114
private void Connected( IAsyncResult ar )
115
{
116
try
117
{
118
Socket sock = (Socket)ar.AsyncState;
119
120
if( sock.Connected )
121
{
122
if(OnConnect != null)
123
{
124
//连接成功事件
125
UpdateEventMessage("连接远程服务器成功");
126
OnConnect(this,socketEventArgs);
127
}
128
}
129
else
130
{
131
//连接失败事件
132
this.HandlerException("连接远程服务器失败");
133
134
}
135
}
136
catch(Exception ex)
137
{
138
this.Close();
139
this.HandlerException(ex.Message);
140
}
141
}
142
#endregion
143
144
异步发送数据异步发送数据#region 异步发送数据
145
146
public void Send(string msg)
147
{
148
byte[] msgBytes = Encoding.ASCII.GetBytes(msg);
149
Send(msgBytes);
150
151
}
152
153
public void Send(byte [] msgBytes)
154
{
155
try
156
{
157
if( this.socket == null || !this.socket.Connected )
158
{
159
throw new Exception("远程服务器没有连接,请先连接");
160
}
161
else
162
{
163
AsyncCallback sendData = new AsyncCallback(SendCallback);
164
this.socket.BeginSend(msgBytes,0,msgBytes.Length,SocketFlags.None,sendData,socket);
165
}
166
}
167
catch(Exception ex)
168
{
169
this.Close();
170
this.HandlerException(ex.Message);
171
}
172
173
}
174
175
176
private void SendCallback(IAsyncResult ar)
177
{
178
try
179
{
180
Socket client = (Socket) ar.AsyncState;
181
int bytesSent = client.EndSend(ar);
182
183
if( bytesSent > 0)
184
{
185
if( this.OnSendFinished != null)
186
{
187
UpdateEventMessage("发送数据成功");
188
OnSendFinished(this,socketEventArgs);
189
}
190
}
191
else
192
{
193
this.HandlerException("发送数据失败");
194
}
195
196
}
197
catch (Exception ex)
198
{
199
this.Close();
200
this.HandlerException(ex.Message);
201
}
202
}
203
204
205
#endregion
206
207
异步接受数据异步接受数据#region 异步接受数据
208
209
public void Receive()
210
{
211
try
212
{
213
if( this.socket == null || !this.socket.Connected )
214
{
215
throw new Exception("远程服务器没有连接,请先连接");
216
}
217
else
218
{
219
AsyncCallback recieveData = new AsyncCallback( OnReceiveData );
220
socket.BeginReceive( buffer, 0, buffer.Length, SocketFlags.None, recieveData, socket );
221
}
222
}
223
catch( Exception ex )
224
{
225
this.Close();
226
this.HandlerException(ex.Message);
227
}
228
}
229
230
231
private void OnReceiveData(IAsyncResult ar)
232
{
233
Socket sock = (Socket)ar.AsyncState;
234
try
235
{
236
int nBytesRec = sock.EndReceive( ar );
237
if( nBytesRec > 0 )
238
{
239
//接受数据并保存
240
string sRecieved = Encoding.ASCII.GetString(buffer, 0, nBytesRec );
241
receiveData.Append(sRecieved);
242
Receive();
243
}
244
else
245
{
246
sock.Shutdown( SocketShutdown.Both );
247
sock.Close();
248
if(receiveData.Length != 0)
249
{
250
if(OnReceivedFinshed != null)
251
{
252
UpdateEventMessage("接受数据成功");
253
OnReceivedFinshed(this,socketEventArgs);
254
}
255
}
256
else
257
{
258
this.HandlerException("接受数据为空");
259
}
260
}
261
}
262
catch( Exception ex )
263
{
264
this.Close();
265
this.HandlerException(ex.Message);
266
}
267
}
268
269
270
#endregion
271
272
接收到的数据接收到的数据#region 接收到的数据
273
/**//**//**//// <summary>
274
/// 接收到的数据
275
/// </summary>
276
public string ReceivedData
277
{
278
get
279
{
280
lock(this)
281
{
282
return this.receiveData.ToString();
283
}
284
}
285
}
286
287
#endregion
288
289
关闭socket关闭socket#region 关闭socket
290
291
public void Close()
292
{
293
try
294
{
295
if( socket != null && socket.Connected )
296
{
297
socket.Shutdown( SocketShutdown.Both );
298
System.Threading.Thread.Sleep( 10 );
299
socket.Close();
300
}
301
}
302
catch(Exception ex)
303
{
304
this.HandlerException(ex.Message);
305
}
306
}
307
308
#endregion
309
310
311
}
312
}
313
业务类在对此包装的socket进行访问时,由于是三个线程之间进行通讯,这个线程无法捕捉另一个线程产生的异常,所以通过信号量来通知是否有异常的产生:
1
#define TEST
2
3
using System;
4
using System.Threading;
5
using System.Text;
6
using Beijing.Traffic.Mobile.Net;
7
8
namespace Beijing.Traffic.Mobile.Bussiness
9

{
10
11
/**//**//**//// <summary>
12
/// 业务逻辑的基类。
13
/// </summary>
14
public abstract class BussinessBase
15
{
16
#if TEST
17
//手机Socket客户端
18
public MobileClient mobileClient = null;
19
20
#else
21
protected MobileClient mobileClient = null;
22
#endif
23
24
protected byte[] receicedBytes = null;
25
//是否产生了Socket异常
26
private bool hasException = false;
27
//异常消息类
28
private Exception socketException = null;
29
30
//三个线程通知事件
31
protected ManualResetEvent connectDone = new ManualResetEvent(false);
32
protected ManualResetEvent sendDone = new ManualResetEvent(false);
33
protected ManualResetEvent receiveDone = new ManualResetEvent(false);
34
35
public BussinessBase()
36
{
37
}
38
/**//**//**//// <summary>
39
/// 获取手机网络连接客户端类
40
/// </summary>
41
/// <returns></returns>
42
public MobileClient GetMobileClient()
43
{
44
45
if(mobileClient == null)
46
{
47
mobileClient = new MobileClient("210.73.74.200","3333");
48
mobileClient.OnConnect += new EventHandler(mobileClient_OnConnect);
49
mobileClient.OnSendFinished +=new EventHandler(mobileClient_OnSendFinished);
50
mobileClient.OnReceivedFinshed +=new EventHandler(mobileClient_OnReceivedFinshed);
51
mobileClient.OnException += new EventHandler(mobileClient_OnException);
52
}
53
return mobileClient;
54
}
55
56
57
事件事件#region 事件
58
protected void mobileClient_OnConnect(object sender, System.EventArgs e)
59
{
60
this.connectDone.Set();
61
}
62
protected void mobileClient_OnException(object sender, System.EventArgs e)
63
{
64
SocketEventArgs socketEventArgs = e as SocketEventArgs;
65
ChangeExceptionStatus(true);
66
UpdateExceptionMessage(socketEventArgs.Message);
67
this.connectDone.Set();
68
}
69
protected void mobileClient_OnSendFinished(object sender, System.EventArgs e)
70
{
71
ChangeExceptionStatus(false);
72
this.sendDone.Set();
73
}
74
protected void mobileClient_OnReceivedFinshed(object sender, System.EventArgs e)
75
{
76
ChangeExceptionStatus(false);
77
this.receiveDone.Set();
78
}
79
#endregion
80
81
82
处理异常处理异常#region 处理异常
83
/**//**//**//// <summary>
84
/// 改变异常信号量
85
/// </summary>
86
/// <param name="hasException"></param>
87
private void ChangeExceptionStatus(bool hasException)
88
{
89
lock(this)
90
{
91
this.hasException = hasException;
92
}
93
}
94
/**//**//**//// <summary>
95
/// 生成异常类
96
/// </summary>
97
/// <param name="msg"></param>
98
private void UpdateExceptionMessage(string msg)
99
{
100
socketException = new Exception(msg);
101
}
102
/**//**//**//// <summary>
103
/// 判断是否产生了异常
104
/// </summary>
105
private void HasException()
106
{
107
lock(this)
108
{
109
if(hasException == true)
110
{
111
throw socketException;
112
}
113
}
114
}
115
#endregion
116
117
118
业务业务#region 业务
119
/**//**//**//// <summary>
120
/// 作一次业务请求
121
/// </summary>
122
/// <param name="package"></param>
123
protected void BusinessRequet(byte[] package)
124
{
125
MobileClient mobileClient = this.GetMobileClient();
126
mobileClient.Connect();
127
this.connectDone.WaitOne();
128
HasException();
129
130
mobileClient.Send(package);
131
this.sendDone.WaitOne();
132
HasException();
133
134
mobileClient.Receive();
135
this.receiveDone.WaitOne();
136
HasException();
137
138
receicedBytes = Encoding.ASCII.GetBytes( mobileClient.ReceivedData);
139
mobileClient.Close();
140
141
}
142
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步