在一个blog上看到的好帖,写了一个对网络 socket 进行封装的类,主要是在异步阻塞模式下进行数据、文件的发送的发送和接收,都是静态方法。代码如下:
1
using
System;
2
using
System.Net;
3
using
System.Net.Sockets;
4
using
System.IO;
5
using
LogDll;
6
7
namespace
NetDll
8
{
9
//<summary>
10
///Net:提供静态方法,对常用的网络操作进行封装
11
///</summary>
12
publicsealedclassNet
13
{
14
privateNet(){
15
}
16
17
/**////<summary>
18
///连接使用tcp协议的服务端
19
///</summary>
20
///<paramname="ip">服务端的ip地址</param>
21
///<paramname="port">服务端的端口号</param>
22
///<returns></returns>
23
publicstaticSocketConnectServer(stringip,intport){
24
Sockets=null;
25
26
try{
27
IPAddressipAddress=IPAddress.Parse(ip);
28
IPEndPointipEndPoint=newIPEndPoint(ipAddress,port);
29
s=newSocket(ipEndPoint.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
30
s.Connect(ipEndPoint);
31
if(s.Connected==false){
32
s=null;
33
}
34
}
35
catch(Exceptione){
36
Log.WriteLog(e);
37
}
38
returns;
39
}
40
41
/**////<summary>
42
///用主机名称连接使用Tcp协议的服务端
43
///</summary>
44
///<paramname="hostName">在hosts文件中存在的主机名称</param>
45
///<paramname="port">服务端的端口号</param>
46
///<returns></returns>
47
publicstaticSocketConnectServByHostName(stringhostName,intport){
48
Sockets=null;
49
IPHostEntryiphe=null;
50
51
try{
52
iphe=Dns.Resolve(hostName);
53
foreach(IPAddressipadiniphe.AddressList){
54
IPEndPointipe=newIPEndPoint(ipad,port);
55
Sockettmps=newSocket(ipe.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
56
tmps.Connect(ipe);
57
58
if(tmps.Connected){
59
s=tmps;
60
break;
61
}
62
else
63
continue;
64
}
65
}
66
catch(Exceptione){
67
Log.WriteLog(e);
68
}
69
returns;
70
}
71
72
/**////<summary>
73
///向远程主机发送数据
74
///</summary>
75
///<paramname="socket">要发送数据且已经连接到远程主机的Socket</param>
76
///<paramname="buffer">待发送的数据</param>
77
///<paramname="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>
78
///<returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>
79
///<remarks>
80
///当outTime指定为-1时,将一直等待直到有数据需要发送
81
///</remarks>
82
publicstaticintSendData(Socketsocket,byte[]buffer,intoutTime){
83
if(socket==null||socket.Connected==false){
84
thrownewArgumentException("参数socket为null,或者未连接到远程计算机");
85
}
86
if(buffer==null||buffer.Length==0){
87
thrownewArgumentException("参数buffer为null,或者长度为0");
88
}
89
90
intflag=0;
91
try{
92
intleft=buffer.Length;
93
intsndLen=0;
94
95
while(true){
96
if((socket.Poll(outTime*1000000,SelectMode.SelectWrite)==true)){//收集了足够多的传出数据后开始发送
97
sndLen=socket.Send(buffer,sndLen,left,SocketFlags.None);
98
left-=sndLen;
99
if(left==0)//数据已经全部发送
100
flag=0;
101
break;
102
}
103
else{
104
if(sndLen>0){//数据部分已经被发送
105
continue;
106
}
107
else{//发送数据发生错误
108
flag=-2;
109
break;
110
}
111
}
112
}
113
else{//超时退出
114
flag=-1;
115
break;
116
}
117
}
118
}
119
catch(SocketExceptione){
120
Log.WriteLog(e);
121
flag=-3;
122
}
123
returnflag;
124
}
125
126
127
/**////<summary>
128
///向远程主机发送数据
129
///</summary>
130
///<paramname="socket">要发送数据且已经连接到远程主机的Socket</param>
131
///<paramname="buffer">待发送的字符串</param>
132
///<paramname="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>
133
///<returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>
134
///<remarks>
135
///当outTime指定为-1时,将一直等待直到有数据需要发送
136
///</remarks>
137
publicstaticintSendData(Socketsocket,stringbuffer,intoutTime){
138
if(buffer==null||buffer.Length==0){
139
thrownewArgumentException("待发送的字符串长度不能为零.");
140
}
141
return(SendData(socket,System.Text.Encoding.Default.GetBytes(buffer),outTime));
142
}
143
144
145
/**////<summary>
146
///接收远程主机发送的数据
147
///</summary>
148
///<paramname="socket">要接收数据且已经连接到远程主机的socket</param>
149
///<paramname="buffer">接收数据的缓冲区</param>
150
///<paramname="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>
151
///<returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>
152
///<remarks>
153
///1、当outTime指定为-1时,将一直等待直到有数据需要接收;
154
///2、需要接收的数据的长度,由buffer的长度决定。
155
///</remarks>
156
publicstaticintRecvData(Socketsocket,byte[]buffer,intoutTime){
157
if(socket==null||socket.Connected==false){
158
thrownewArgumentException("参数socket为null,或者未连接到远程计算机");
159
}
160
if(buffer==null||buffer.Length==0){
161
thrownewArgumentException("参数buffer为null,或者长度为0");
162
}
163
buffer.Initialize();
164
intleft=buffer.Length;
165
intcurRcv=0;
166
intflag=0;
167
168
try{
169
while(true){
170
if(socket.Poll(outTime*1000000,SelectMode.SelectRead)==true){//已经有数据等待接收
171
curRcv=socket.Receive(buffer,curRcv,left,SocketFlags.None);
172
left-=curRcv;
173
if(left==0){//数据已经全部接收
174
flag=0;
175
break;
176
}
177
else{
178
if(curRcv>0){//数据已经部分接收
179
continue;
180
}
181
else{//出现错误
182
flag=-2;
183
break;
184
}
185
}
186
}
187
else{//超时退出
188
flag=-1;
189
break;
190
}
191
}
192
}
193
catch(SocketExceptione){
194
Log.WriteLog(e);
195
flag=-3;
196
}
197
returnflag;
198
}
199
200
/**////<summary>
201
///接收远程主机发送的数据
202
///</summary>
203
///<paramname="socket">要接收数据且已经连接到远程主机的socket</param>
204
///<paramname="buffer">存储接收到的数据的字符串</param>
205
///<paramname="bufferLen">待接收的数据的长度</param>
206
///<paramname="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>
207
///<returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>
208
///<remarks>
209
///当outTime指定为-1时,将一直等待直到有数据需要接收;
210
///</remarks>
211
publicstaticintRecvData(Socketsocket,stringbuffer,intbufferLen,intoutTime){
212
if(bufferLen<=0){
213
thrownewArgumentException("存储待接收数据的缓冲区长度必须大于0");
214
}
215
byte[]tmp=newbyte[bufferLen];
216
intflag=0;
217
if((flag=RecvData(socket,tmp,outTime))==0){
218
buffer=System.Text.Encoding.Default.GetString(tmp);
219
}
220
returnflag;
221
}
222
223
224
/**////<summary>
225
///向远程主机发送文件
226
///</summary>
227
///<paramname="socket">要发送数据且已经连接到远程主机的socket</param>
228
///<paramname="fileName">待发送的文件名称</param>
229
///<paramname="maxBufferLength">文件发送时的缓冲区大小</param>
230
///<paramname="outTime">发送缓冲区中的数据的超时时间</param>
231
///<returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>
232
///<remarks>
233
///当outTime指定为-1时,将一直等待直到有数据需要发送
234
///</remarks>
235
publicstaticintSendFile(Socketsocket,stringfileName,intmaxBufferLength,intoutTime){
236
if(fileName==null||maxBufferLength<=0){
237
thrownewArgumentException("待发送的文件名称为空或发送缓冲区的大小设置不正确.");
238
}
239
240
intflag=0;
241
try{
242
FileStreamfs=newFileStream(fileName,FileMode.Open,FileAccess.Read);
243
longfileLen=fs.Length;//文件长度
244
longleftLen=fileLen;//未读取部分
245
intreadLen=0;//已读取部分
246
byte[]buffer=null;
247
248
if(fileLen<=maxBufferLength){/**//*文件可以一次读取*/
249
buffer=newbyte[fileLen];
250
readLen=fs.Read(buffer,0,(int)fileLen);
251
flag=SendData(socket,buffer,outTime);
252
}
253
else{/**//*循环读取文件,并发送*/
254
buffer=newbyte[maxBufferLength];
255
while(leftLen!=0){
256
readLen=fs.Read(buffer,0,maxBufferLength);
257
if((flag=SendData(socket,buffer,outTime))<0){
258
break;
259
}
260
leftLen-=readLen;
261
}
262
}
263
fs.Close();
264
}
265
catch(IOExceptione){
266
Log.WriteLog(e);
267
flag=-4;
268
}
269
returnflag;
270
}
271
272
/**////<summary>
273
///向远程主机发送文件
274
///</summary>
275
///<paramname="socket">要发送数据且已经连接到远程主机的socket</param>
276
///<paramname="fileName">待发送的文件名称</param>
277
///<returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>
278
publicstaticintSendFile(Socketsocket,stringfileName){
279
returnSendFile(socket,fileName,2048,1);
280
}
281
282
283
/**////<summary>
284
///接收远程主机发送的文件
285
///</summary>
286
///<paramname="socket">待接收数据且已经连接到远程主机的socket</param>
287
///<paramname="fileName">保存接收到的数据的文件名</param>
288
///<paramname="fileLength">待接收的文件的长度</param>
289
///<paramname="maxBufferLength">接收文件时最大的缓冲区大小</param>
290
///<paramname="outTime">接受缓冲区数据的超时时间</param>
291
///<returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>
292
///<remarks>
293
///当outTime指定为-1时,将一直等待直到有数据需要接收
294
///</remarks>
295
publicstaticintRecvFile(Socketsocket,stringfileName,longfileLength,intmaxBufferLength,intoutTime){
296
if(fileName==null||maxBufferLength<=0){
297
thrownewArgumentException("保存接收数据的文件名称为空或发送缓冲区的大小设置不正确.");
298
}
299
300
intflag=0;
301
try{
302
FileStreamfs=newFileStream(fileName,FileMode.Create);
303
byte[]buffer=null;
304
305
if(fileLength<=maxBufferLength){/**//*一次读取所传送的文件*/
306
buffer=newbyte[fileLength];
307
if((flag=RecvData(socket,buffer,outTime))==0){
308
fs.Write(buffer,0,(int)fileLength);
309
}
310
}
311
else{/**//*循环读取网络数据,并写入文件*/
312
intrcvLen=maxBufferLength;
313
longleftLen=fileLength;//剩下未写入的数据
314
buffer=newbyte[rcvLen];
315
316
while(leftLen!=0){
317
if((flag=RecvData(socket,buffer,outTime))<0){
318
break;
319
}
320
fs.Write(buffer,0,rcvLen);
321
leftLen-=rcvLen;
322
rcvLen=(maxBufferLength<leftLen)?maxBufferLength:((int)leftLen);
323
}
324
}
325
fs.Close();
326
}
327
catch(IOExceptione){
328
Log.WriteLog(e);
329
flag=-4;
330
}
331
returnflag;
332
}
333
334
/**////<summary>
335
///接收远程主机发送的文件
336
///</summary>
337
///<paramname="socket">待接收数据且已经连接到远程主机的socket</param>
338
///<paramname="fileName">保存接收到的数据的文件名</param>
339
///<paramname="fileLength">待接收的文件的长度</param>
340
///<returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>
341
publicstaticintRecvFile(Socketsocket,stringfileName,longfileLength){
342
returnRecvFile(socket,fileName,fileLength,2048,1);
343
}
344
}
345
}
346

2

3

4

5

6

7

8


9


10

11

12

13


14


15

16

17


18

19

20

21

22

23


24

25

26


27

28

29

30

31


32

33

34

35


36

37

38

39

40

41


42

43

44

45

46

47


48

49

50

51


52

53


54

55

56

57

58


59

60

61

62

63

64

65

66


67

68

69

70

71

72


73

74

75

76

77

78

79

80

81

82


83


84

85

86


87

88

89

90

91


92

93

94

95


96


97

98

99


100

101

102

103


104


105

106

107


108

109

110

111

112

113


114

115

116

117

118

119


120

121

122

123

124

125

126

127


128

129

130

131

132

133

134

135

136

137


138


139

140

141

142

143

144

145


146

147

148

149

150

151

152

153

154

155

156


157


158

159

160


161

162

163

164

165

166

167

168


169


170


171

172

173


174

175

176

177


178


179

180

181


182

183

184

185

186

187


188

189

190

191

192

193


194

195

196

197

198

199

200


201

202

203

204

205

206

207

208

209

210

211


212


213

214

215

216

217


218

219

220

221

222

223

224


225

226

227

228

229

230

231

232

233

234

235


236


237

238

239

240

241


242

243

244

245

246

247

248


249

250

251

252

253


254

255


256

257


258

259

260

261

262

263

264

265


266

267

268

269

270

271

272


273

274

275

276

277

278


279

280

281

282

283


284

285

286

287

288

289

290

291

292

293

294

295


296


297

298

299

300

301


302

303

304

305


306

307


308

309

310

311


312

313

314

315

316


317


318

319

320

321

322

323

324

325

326

327


328

329

330

331

332

333

334


335

336

337

338

339

340

341


342

343

344

345

346

在这个类中用到了一个 LogDll 的组件,主要完成发生异常或错误的时候,将信息输出到日志文件。用到了“ winform 程序的配置文件——App.config ”中提到的内容,代码如下:
1
#define
DEBUG
2
3
using
System;
4
using
System.Diagnostics;
5
6
namespace
LogDll
7
{
8
/**////<summary>
9
///Log:将系统运行信息写入到日志文件
10
///</summary>
11
///<remarks>需要在项目的配置文件中增加如下的信息:
12
///<configuration>
13
///<system.diagnostics>
14
///<switches>
15
///<addname="MagicTraceSwitch"value="3"/>
16
///</switches>
17
///<traceautoflush="true"indentsize="4">
18
///<listeners>
19
///<addname="myListener"type="System.Diagnostics.TextWriterTraceListener"initializeData="myListener.log"/>
20
///<removetype="System.Diagnostics.DefaultTraceListener"/>
21
///</listeners>
22
///</trace>
23
///</system.diagnostics>
24
///</configuration>
25
///其中的initializeData="myListener.log",替换为自己的日志文件名称
26
///</remarks>
27
publicclassLog
28
{
29
privateLog(){
30
}
31
32
publicstaticvoidWriteLog(Exceptione){
33
Debug.WriteLine(DateTime.Now.ToString()+":"+e.Message+"["+e.StackTrace+"]");
34
}
35
36
publicstaticvoidWriteLog(stringmessage,stringsourceFile){
37
Debug.WriteLine(DateTime.Now.ToString()+":"+message+"["+sourceFile+"]");
38
}
39
40
publicstaticvoidWriteLog(stringmessage){
41
Debug.WriteLine(DateTime.Now.ToString()+":"+message);
42
}
43
}
44
}
45

2

3

4

5

6

7


8


9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28


29


30

31

32


33

34

35

36


37

38

39

40


41

42

43

44

45
