近日,写了一个对网络 socket 进行封装的类,主要是在异步阻塞模式下进行数据、文件的发送的发送和接收,都是静态方法。代码如下:
在这个类中用到了一个 LogDll 的组件,主要完成发生异常或错误的时候,将信息输出到日志文件。用到了“winform 程序的配置文件——App.config ”中提到的内容,代码如下:
1using System;
2using System.Net ;
3using System.Net.Sockets ;
4using System.IO ;
5using LogDll;
6
7namespace NetDll
8{
9 /// <summary>
10 /// Net : 提供静态方法,对常用的网络操作进行封装
11 /// </summary>
12 public sealed class Net
13 {
14 private Net(){
15 }
16
17 /// <summary>
18 /// 连接使用 tcp 协议的服务端
19 /// </summary>
20 /// <param name="ip">服务端的ip地址</param>
21 /// <param name="port">服务端的端口号</param>
22 /// <returns></returns>
23 public static Socket ConnectServer( string ip ,int port ) {
24 Socket s = null;
25
26 try {
27 IPAddress ipAddress = IPAddress.Parse ( ip );
28 IPEndPoint ipEndPoint = new IPEndPoint ( ipAddress,port );
29 s = new Socket ( ipEndPoint.AddressFamily ,SocketType.Stream ,ProtocolType.Tcp );
30 s.Connect ( ipEndPoint );
31 if ( s.Connected== false ) {
32 s = null;
33 }
34 }
35 catch ( Exception e ) {
36 Log.WriteLog ( e );
37 }
38 return s;
39 }
40
41 /// <summary>
42 /// 用主机名称连接使用Tcp协议的服务端
43 /// </summary>
44 /// <param name="hostName">在hosts 文件中存在的主机名称</param>
45 /// <param name="port">服务端的端口号</param>
46 /// <returns></returns>
47 public static Socket ConnectServByHostName( string hostName,int port ){
48 Socket s = null;
49 IPHostEntry iphe = null;
50
51 try {
52 iphe = Dns.Resolve ( hostName );
53 foreach ( IPAddress ipad in iphe.AddressList ) {
54 IPEndPoint ipe = new IPEndPoint (ipad,port);
55 Socket tmps = new Socket (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 ( Exception e ) {
67 Log.WriteLog ( e );
68 }
69 return s;
70 }
71
72 /// <summary>
73 /// 向远程主机发送数据
74 /// </summary>
75 /// <param name="socket">要发送数据且已经连接到远程主机的 Socket</param>
76 /// <param name="buffer">待发送的数据</param>
77 /// <param name="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>
78 /// <returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>
79 /// <remarks >
80 /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
81 /// </remarks>
82 public static int SendData ( Socket socket,byte[] buffer,int outTime ) {
83 if ( socket == null ||socket.Connected == false ) {
84 throw new ArgumentException ("参数socket 为null,或者未连接到远程计算机");
85 }
86 if ( buffer == null || buffer.Length == 0 ) {
87 throw new ArgumentException ("参数buffer 为null ,或者长度为 0");
88 }
89
90 int flag = 0;
91 try {
92 int left = buffer.Length ;
93 int sndLen = 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 ( SocketException e ) {
120 Log.WriteLog ( e );
121 flag = -3;
122 }
123 return flag;
124 }
125
126
127 /// <summary>
128 /// 向远程主机发送数据
129 /// </summary>
130 /// <param name="socket">要发送数据且已经连接到远程主机的 Socket</param>
131 /// <param name="buffer">待发送的字符串</param>
132 /// <param name="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>
133 /// <returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>
134 /// <remarks >
135 /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
136 /// </remarks>
137 public static int SendData ( Socket socket,string buffer,int outTime ) {
138 if ( buffer == null || buffer.Length == 0 ) {
139 throw new ArgumentException ("待发送的字符串长度不能为零.");
140 }
141 return ( SendData ( socket,System.Text .Encoding .Default .GetBytes ( buffer ),outTime) );
142 }
143
144
145 /// <summary>
146 /// 接收远程主机发送的数据
147 /// </summary>
148 /// <param name="socket">要接收数据且已经连接到远程主机的 socket</param>
149 /// <param name="buffer">接收数据的缓冲区</param>
150 /// <param name="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>
151 /// <returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>
152 /// <remarks >
153 /// 1、当 outTime 指定为-1时,将一直等待直到有数据需要接收;
154 /// 2、需要接收的数据的长度,由 buffer 的长度决定。
155 /// </remarks>
156 public static int RecvData ( Socket socket,byte[] buffer ,int outTime ) {
157 if ( socket == null || socket.Connected == false ) {
158 throw new ArgumentException ("参数socket 为null,或者未连接到远程计算机");
159 }
160 if ( buffer == null || buffer.Length == 0 ) {
161 throw new ArgumentException ("参数buffer 为null ,或者长度为 0");
162 }
163 buffer.Initialize ();
164 int left = buffer.Length ;
165 int curRcv = 0;
166 int flag = 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 ( SocketException e ) {
194 Log.WriteLog ( e );
195 flag = -3;
196 }
197 return flag;
198 }
199
200 /// <summary>
201 /// 接收远程主机发送的数据
202 /// </summary>
203 /// <param name="socket">要接收数据且已经连接到远程主机的 socket</param>
204 /// <param name="buffer">存储接收到的数据的字符串</param>
205 /// <param name="bufferLen">待接收的数据的长度</param>
206 /// <param name="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>
207 /// <returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>
208 /// <remarks >
209 /// 当 outTime 指定为-1时,将一直等待直到有数据需要接收;
210 /// </remarks>
211 public static int RecvData ( Socket socket,string buffer ,int bufferLen,int outTime ) {
212 if ( bufferLen <= 0 ) {
213 throw new ArgumentException ("存储待接收数据的缓冲区长度必须大于0");
214 }
215 byte[] tmp = new byte [ bufferLen ];
216 int flag = 0;
217 if ( ( flag = RecvData ( socket,tmp,outTime)) == 0) {
218 buffer = System.Text.Encoding .Default .GetString ( tmp );
219 }
220 return flag;
221 }
222
223
224 /// <summary>
225 /// 向远程主机发送文件
226 /// </summary>
227 /// <param name="socket" >要发送数据且已经连接到远程主机的 socket</param>
228 /// <param name="fileName">待发送的文件名称</param>
229 /// <param name="maxBufferLength">文件发送时的缓冲区大小</param>
230 /// <param name="outTime">发送缓冲区中的数据的超时时间</param>
231 /// <returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>
232 /// <remarks >
233 /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
234 /// </remarks>
235 public static int SendFile ( Socket socket ,string fileName,int maxBufferLength,int outTime ) {
236 if ( fileName == null || maxBufferLength <= 0 ) {
237 throw new ArgumentException ("待发送的文件名称为空或发送缓冲区的大小设置不正确.");
238 }
239
240 int flag = 0;
241 try {
242 FileStream fs = new FileStream ( fileName,FileMode.Open ,FileAccess.Read );
243 long fileLen = fs.Length ; // 文件长度
244 long leftLen = fileLen; // 未读取部分
245 int readLen = 0; // 已读取部分
246 byte[] buffer = null;
247
248 if ( fileLen <= maxBufferLength ) { /* 文件可以一次读取*/
249 buffer = new byte [ fileLen ];
250 readLen = fs.Read (buffer,0,(int )fileLen );
251 flag = SendData( socket,buffer,outTime );
252 }
253 else { /* 循环读取文件,并发送 */
254 buffer = new byte[ 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 ( IOException e ) {
266 Log.WriteLog ( e );
267 flag = -4;
268 }
269 return flag;
270 }
271
272 /// <summary>
273 /// 向远程主机发送文件
274 /// </summary>
275 /// <param name="socket" >要发送数据且已经连接到远程主机的 socket</param>
276 /// <param name="fileName">待发送的文件名称</param>
277 /// <returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>
278 public static int SendFile ( Socket socket ,string fileName ) {
279 return SendFile ( socket,fileName,2048,1 );
280 }
281
282
283 /// <summary>
284 /// 接收远程主机发送的文件
285 /// </summary>
286 /// <param name="socket">待接收数据且已经连接到远程主机的 socket</param>
287 /// <param name="fileName">保存接收到的数据的文件名</param>
288 /// <param name="fileLength" >待接收的文件的长度</param>
289 /// <param name="maxBufferLength">接收文件时最大的缓冲区大小</param>
290 /// <param name="outTime">接受缓冲区数据的超时时间</param>
291 /// <returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>
292 /// <remarks >
293 /// 当 outTime 指定为-1时,将一直等待直到有数据需要接收
294 /// </remarks>
295 public static int RecvFile ( Socket socket ,string fileName,long fileLength,int maxBufferLength,int outTime ) {
296 if ( fileName == null || maxBufferLength <= 0 ) {
297 throw new ArgumentException ("保存接收数据的文件名称为空或发送缓冲区的大小设置不正确.");
298 }
299
300 int flag = 0;
301 try {
302 FileStream fs = new FileStream (fileName,FileMode.Create);
303 byte [] buffer = null;
304
305 if ( fileLength <= maxBufferLength ) { /* 一次读取所传送的文件 */
306 buffer = new byte [ fileLength ];
307 if ( ( flag =RecvData(socket,buffer,outTime ) ) == 0 ) {
308 fs.Write ( buffer,0,(int)fileLength);
309 }
310 }
311 else { /* 循环读取网络数据,并写入文件 */
312 int rcvLen = maxBufferLength;
313 long leftLen = fileLength; //剩下未写入的数据
314 buffer = new byte [ 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 ( IOException e ) {
328 Log.WriteLog ( e );
329 flag = -4;
330 }
331 return flag;
332 }
333
334 /// <summary>
335 /// 接收远程主机发送的文件
336 /// </summary>
337 /// <param name="socket">待接收数据且已经连接到远程主机的 socket</param>
338 /// <param name="fileName">保存接收到的数据的文件名</param>
339 /// <param name="fileLength" >待接收的文件的长度</param>
340 /// <returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>
341 public static int RecvFile ( Socket socket,string fileName,long fileLength ) {
342 return RecvFile ( socket,fileName,fileLength,2048,1);
343 }
344 }
345}
346
2using System.Net ;
3using System.Net.Sockets ;
4using System.IO ;
5using LogDll;
6
7namespace NetDll
8{
9 /// <summary>
10 /// Net : 提供静态方法,对常用的网络操作进行封装
11 /// </summary>
12 public sealed class Net
13 {
14 private Net(){
15 }
16
17 /// <summary>
18 /// 连接使用 tcp 协议的服务端
19 /// </summary>
20 /// <param name="ip">服务端的ip地址</param>
21 /// <param name="port">服务端的端口号</param>
22 /// <returns></returns>
23 public static Socket ConnectServer( string ip ,int port ) {
24 Socket s = null;
25
26 try {
27 IPAddress ipAddress = IPAddress.Parse ( ip );
28 IPEndPoint ipEndPoint = new IPEndPoint ( ipAddress,port );
29 s = new Socket ( ipEndPoint.AddressFamily ,SocketType.Stream ,ProtocolType.Tcp );
30 s.Connect ( ipEndPoint );
31 if ( s.Connected== false ) {
32 s = null;
33 }
34 }
35 catch ( Exception e ) {
36 Log.WriteLog ( e );
37 }
38 return s;
39 }
40
41 /// <summary>
42 /// 用主机名称连接使用Tcp协议的服务端
43 /// </summary>
44 /// <param name="hostName">在hosts 文件中存在的主机名称</param>
45 /// <param name="port">服务端的端口号</param>
46 /// <returns></returns>
47 public static Socket ConnectServByHostName( string hostName,int port ){
48 Socket s = null;
49 IPHostEntry iphe = null;
50
51 try {
52 iphe = Dns.Resolve ( hostName );
53 foreach ( IPAddress ipad in iphe.AddressList ) {
54 IPEndPoint ipe = new IPEndPoint (ipad,port);
55 Socket tmps = new Socket (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 ( Exception e ) {
67 Log.WriteLog ( e );
68 }
69 return s;
70 }
71
72 /// <summary>
73 /// 向远程主机发送数据
74 /// </summary>
75 /// <param name="socket">要发送数据且已经连接到远程主机的 Socket</param>
76 /// <param name="buffer">待发送的数据</param>
77 /// <param name="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>
78 /// <returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>
79 /// <remarks >
80 /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
81 /// </remarks>
82 public static int SendData ( Socket socket,byte[] buffer,int outTime ) {
83 if ( socket == null ||socket.Connected == false ) {
84 throw new ArgumentException ("参数socket 为null,或者未连接到远程计算机");
85 }
86 if ( buffer == null || buffer.Length == 0 ) {
87 throw new ArgumentException ("参数buffer 为null ,或者长度为 0");
88 }
89
90 int flag = 0;
91 try {
92 int left = buffer.Length ;
93 int sndLen = 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 ( SocketException e ) {
120 Log.WriteLog ( e );
121 flag = -3;
122 }
123 return flag;
124 }
125
126
127 /// <summary>
128 /// 向远程主机发送数据
129 /// </summary>
130 /// <param name="socket">要发送数据且已经连接到远程主机的 Socket</param>
131 /// <param name="buffer">待发送的字符串</param>
132 /// <param name="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>
133 /// <returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>
134 /// <remarks >
135 /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
136 /// </remarks>
137 public static int SendData ( Socket socket,string buffer,int outTime ) {
138 if ( buffer == null || buffer.Length == 0 ) {
139 throw new ArgumentException ("待发送的字符串长度不能为零.");
140 }
141 return ( SendData ( socket,System.Text .Encoding .Default .GetBytes ( buffer ),outTime) );
142 }
143
144
145 /// <summary>
146 /// 接收远程主机发送的数据
147 /// </summary>
148 /// <param name="socket">要接收数据且已经连接到远程主机的 socket</param>
149 /// <param name="buffer">接收数据的缓冲区</param>
150 /// <param name="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>
151 /// <returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>
152 /// <remarks >
153 /// 1、当 outTime 指定为-1时,将一直等待直到有数据需要接收;
154 /// 2、需要接收的数据的长度,由 buffer 的长度决定。
155 /// </remarks>
156 public static int RecvData ( Socket socket,byte[] buffer ,int outTime ) {
157 if ( socket == null || socket.Connected == false ) {
158 throw new ArgumentException ("参数socket 为null,或者未连接到远程计算机");
159 }
160 if ( buffer == null || buffer.Length == 0 ) {
161 throw new ArgumentException ("参数buffer 为null ,或者长度为 0");
162 }
163 buffer.Initialize ();
164 int left = buffer.Length ;
165 int curRcv = 0;
166 int flag = 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 ( SocketException e ) {
194 Log.WriteLog ( e );
195 flag = -3;
196 }
197 return flag;
198 }
199
200 /// <summary>
201 /// 接收远程主机发送的数据
202 /// </summary>
203 /// <param name="socket">要接收数据且已经连接到远程主机的 socket</param>
204 /// <param name="buffer">存储接收到的数据的字符串</param>
205 /// <param name="bufferLen">待接收的数据的长度</param>
206 /// <param name="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>
207 /// <returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>
208 /// <remarks >
209 /// 当 outTime 指定为-1时,将一直等待直到有数据需要接收;
210 /// </remarks>
211 public static int RecvData ( Socket socket,string buffer ,int bufferLen,int outTime ) {
212 if ( bufferLen <= 0 ) {
213 throw new ArgumentException ("存储待接收数据的缓冲区长度必须大于0");
214 }
215 byte[] tmp = new byte [ bufferLen ];
216 int flag = 0;
217 if ( ( flag = RecvData ( socket,tmp,outTime)) == 0) {
218 buffer = System.Text.Encoding .Default .GetString ( tmp );
219 }
220 return flag;
221 }
222
223
224 /// <summary>
225 /// 向远程主机发送文件
226 /// </summary>
227 /// <param name="socket" >要发送数据且已经连接到远程主机的 socket</param>
228 /// <param name="fileName">待发送的文件名称</param>
229 /// <param name="maxBufferLength">文件发送时的缓冲区大小</param>
230 /// <param name="outTime">发送缓冲区中的数据的超时时间</param>
231 /// <returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>
232 /// <remarks >
233 /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
234 /// </remarks>
235 public static int SendFile ( Socket socket ,string fileName,int maxBufferLength,int outTime ) {
236 if ( fileName == null || maxBufferLength <= 0 ) {
237 throw new ArgumentException ("待发送的文件名称为空或发送缓冲区的大小设置不正确.");
238 }
239
240 int flag = 0;
241 try {
242 FileStream fs = new FileStream ( fileName,FileMode.Open ,FileAccess.Read );
243 long fileLen = fs.Length ; // 文件长度
244 long leftLen = fileLen; // 未读取部分
245 int readLen = 0; // 已读取部分
246 byte[] buffer = null;
247
248 if ( fileLen <= maxBufferLength ) { /* 文件可以一次读取*/
249 buffer = new byte [ fileLen ];
250 readLen = fs.Read (buffer,0,(int )fileLen );
251 flag = SendData( socket,buffer,outTime );
252 }
253 else { /* 循环读取文件,并发送 */
254 buffer = new byte[ 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 ( IOException e ) {
266 Log.WriteLog ( e );
267 flag = -4;
268 }
269 return flag;
270 }
271
272 /// <summary>
273 /// 向远程主机发送文件
274 /// </summary>
275 /// <param name="socket" >要发送数据且已经连接到远程主机的 socket</param>
276 /// <param name="fileName">待发送的文件名称</param>
277 /// <returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>
278 public static int SendFile ( Socket socket ,string fileName ) {
279 return SendFile ( socket,fileName,2048,1 );
280 }
281
282
283 /// <summary>
284 /// 接收远程主机发送的文件
285 /// </summary>
286 /// <param name="socket">待接收数据且已经连接到远程主机的 socket</param>
287 /// <param name="fileName">保存接收到的数据的文件名</param>
288 /// <param name="fileLength" >待接收的文件的长度</param>
289 /// <param name="maxBufferLength">接收文件时最大的缓冲区大小</param>
290 /// <param name="outTime">接受缓冲区数据的超时时间</param>
291 /// <returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>
292 /// <remarks >
293 /// 当 outTime 指定为-1时,将一直等待直到有数据需要接收
294 /// </remarks>
295 public static int RecvFile ( Socket socket ,string fileName,long fileLength,int maxBufferLength,int outTime ) {
296 if ( fileName == null || maxBufferLength <= 0 ) {
297 throw new ArgumentException ("保存接收数据的文件名称为空或发送缓冲区的大小设置不正确.");
298 }
299
300 int flag = 0;
301 try {
302 FileStream fs = new FileStream (fileName,FileMode.Create);
303 byte [] buffer = null;
304
305 if ( fileLength <= maxBufferLength ) { /* 一次读取所传送的文件 */
306 buffer = new byte [ fileLength ];
307 if ( ( flag =RecvData(socket,buffer,outTime ) ) == 0 ) {
308 fs.Write ( buffer,0,(int)fileLength);
309 }
310 }
311 else { /* 循环读取网络数据,并写入文件 */
312 int rcvLen = maxBufferLength;
313 long leftLen = fileLength; //剩下未写入的数据
314 buffer = new byte [ 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 ( IOException e ) {
328 Log.WriteLog ( e );
329 flag = -4;
330 }
331 return flag;
332 }
333
334 /// <summary>
335 /// 接收远程主机发送的文件
336 /// </summary>
337 /// <param name="socket">待接收数据且已经连接到远程主机的 socket</param>
338 /// <param name="fileName">保存接收到的数据的文件名</param>
339 /// <param name="fileLength" >待接收的文件的长度</param>
340 /// <returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>
341 public static int RecvFile ( Socket socket,string fileName,long fileLength ) {
342 return RecvFile ( socket,fileName,fileLength,2048,1);
343 }
344 }
345}
346
在这个类中用到了一个 LogDll 的组件,主要完成发生异常或错误的时候,将信息输出到日志文件。用到了“winform 程序的配置文件——App.config ”中提到的内容,代码如下:
1#define DEBUG
2
3using System;
4using System.Diagnostics ;
5
6namespace LogDll
7{
8 /// <summary>
9 /// Log : 将系统运行信息写入到日志文件
10 /// </summary>
11 /// <remarks >需要在项目的配置文件中增加如下的信息:
12 /// <configuration>
13 /// <system.diagnostics>
14 /// <switches>
15 /// <add name="MagicTraceSwitch" value="3" />
16 /// </switches>
17 /// <trace autoflush="true" indentsize="4">
18 /// <listeners>
19 /// <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="myListener.log" />
20 /// <remove type="System.Diagnostics.DefaultTraceListener" />
21 /// </listeners>
22 /// </trace>
23 /// </system.diagnostics>
24 /// </configuration>
25 /// 其中的initializeData="myListener.log",替换为自己的日志文件名称
26 /// </remarks>
27 public class Log
28 {
29 private Log(){
30 }
31
32 public static void WriteLog ( Exception e ) {
33 Debug.WriteLine ( DateTime.Now .ToString () + ": " + e.Message +" ["+e.StackTrace +"]");
34 }
35
36 public static void WriteLog ( string message,string sourceFile ) {
37 Debug.WriteLine ( DateTime.Now .ToString () + ": " + message + " ["+sourceFile +"]");
38 }
39
40 public static void WriteLog ( string message ) {
41 Debug.WriteLine ( DateTime.Now .ToString () + ": " + message );
42 }
43 }
44}
45
2
3using System;
4using System.Diagnostics ;
5
6namespace LogDll
7{
8 /// <summary>
9 /// Log : 将系统运行信息写入到日志文件
10 /// </summary>
11 /// <remarks >需要在项目的配置文件中增加如下的信息:
12 /// <configuration>
13 /// <system.diagnostics>
14 /// <switches>
15 /// <add name="MagicTraceSwitch" value="3" />
16 /// </switches>
17 /// <trace autoflush="true" indentsize="4">
18 /// <listeners>
19 /// <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="myListener.log" />
20 /// <remove type="System.Diagnostics.DefaultTraceListener" />
21 /// </listeners>
22 /// </trace>
23 /// </system.diagnostics>
24 /// </configuration>
25 /// 其中的initializeData="myListener.log",替换为自己的日志文件名称
26 /// </remarks>
27 public class Log
28 {
29 private Log(){
30 }
31
32 public static void WriteLog ( Exception e ) {
33 Debug.WriteLine ( DateTime.Now .ToString () + ": " + e.Message +" ["+e.StackTrace +"]");
34 }
35
36 public static void WriteLog ( string message,string sourceFile ) {
37 Debug.WriteLine ( DateTime.Now .ToString () + ": " + message + " ["+sourceFile +"]");
38 }
39
40 public static void WriteLog ( string message ) {
41 Debug.WriteLine ( DateTime.Now .ToString () + ": " + message );
42 }
43 }
44}
45