SocketOperation网络通信封装

  1     public sealed class SocketOperation
  2     {
  3         string strBufferLeft = string.Empty;
  4 
  5         public SocketOperation()
  6         {
  7         }
  8 
  9         /**/
 10         /// <summary>  
 11         /// 连接使用 tcp 协议的服务端  
 12         /// </summary>  
 13         /// <param name="ip">服务端的ip地址</param>  
 14         /// <param name="port">服务端的端口号</param>  
 15         /// <returns></returns>  
 16         public Socket ConnectServer(string ip, int port)
 17         {
 18             Socket s = null;
 19 
 20             try
 21             {
 22                 IPAddress ipAddress = IPAddress.Parse(ip);
 23                 IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
 24                 //EndPoint EndPointLocal=(EndPoint)(new IPEndPoint(IPAddress.Parse(Global.PCIP), 35001));
 25 
 26                 s = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
 27                 //s.Bind(EndPointLocal);
 28                 if (0 != Global.TestCount)
 29                 {
 30                     Thread.Sleep(15000);
 31                 }
 32                 //MessageBox.Show(Global.PCIP);
 33                 s.Connect(ipEndPoint);
 34                 //MessageBox.Show(s.Connected.ToString());
 35                 if (s.Connected == false)
 36                 {
 37                     s = null;
 38                 }
 39             }
 40             catch (Exception e)
 41             {
 42                 //Log.WriteLog ( e );  
 43             }
 44             return s;
 45         }
 46 
 47         /**/
 48         /// <summary>  
 49         /// 用主机名称连接使用Tcp协议的服务端  
 50         /// </summary>  
 51         /// <param name="hostName">在hosts 文件中存在的主机名称</param>  
 52         /// <param name="port">服务端的端口号</param>  
 53         /// <returns></returns>  
 54         public Socket ConnectServByHostName(string hostName, int port)
 55         {
 56             Socket s = null;
 57             IPHostEntry iphe = null;
 58 
 59             try
 60             {
 61                 iphe = Dns.Resolve(hostName);
 62                 foreach (IPAddress ipad in iphe.AddressList)
 63                 {
 64                     IPEndPoint ipe = new IPEndPoint(ipad, port);
 65                     Socket tmps = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
 66                     tmps.Connect(ipe);
 67 
 68                     if (tmps.Connected)
 69                     {
 70                         s = tmps;
 71                         break;
 72                     }
 73                     else
 74                         continue;
 75                 }
 76             }
 77             catch (Exception e)
 78             {
 79                 //Log.WriteLog ( e );  
 80             }
 81             return s;
 82         }
 83 
 84         /**/
 85         /// <summary>  
 86         /// 向远程主机发送数据  
 87         /// </summary>  
 88         /// <param name="socket">要发送数据且已经连接到远程主机的 Socket</param>  
 89         /// <param name="buffer">待发送的数据</param>  
 90         /// <param name="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>  
 91         /// <returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>  
 92         /// <remarks >  
 93         /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送  
 94         /// </remarks>  
 95         public int SendData(Socket socket, byte[] buffer, int outTime)
 96         {
 97             if (socket == null || socket.Connected == false)
 98             {
 99                 throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
100             }
101             if (buffer == null || buffer.Length == 0)
102             {
103                 throw new ArgumentException("参数buffer 为null ,或者长度为 0");
104             }
105 
106             int flag = 0;
107             try
108             {
109                 int left = buffer.Length;
110                 int sndLen = 0;
111 
112                 while (true)
113                 {
114                     if ((socket.Poll(outTime * 1000000, SelectMode.SelectWrite) == true))
115                     {        // 收集了足够多的传出数据后开始发送  
116                         sndLen = socket.Send(buffer, sndLen, left, SocketFlags.None);
117                         left -= sndLen;
118                         if (left == 0)
119                         {                                        // 数据已经全部发送  
120                             flag = 0;
121                             break;
122                         }
123                         else
124                         {
125                             if (sndLen > 0)
126                             {                                    // 数据部分已经被发送  
127                                 continue;
128                             }
129                             else
130                             {                                                // 发送数据发生错误  
131                                 flag = -2;
132                                 break;
133                             }
134                         }
135                     }
136                     else
137                     {                                                        // 超时退出  
138                         flag = -1;
139                         break;
140                     }
141                 }
142             }
143             catch (SocketException e)
144             {
145                 //Log.WriteLog ( e );  
146                 flag = -3;
147             }
148             return flag;
149         }
150 
151 
152         /**/
153         /// <summary>  
154         /// 向远程主机发送数据  
155         /// </summary>  
156         /// <param name="socket">要发送数据且已经连接到远程主机的 Socket</param>  
157         /// <param name="buffer">待发送的字符串</param>  
158         /// <param name="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>  
159         /// <returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>  
160         /// <remarks >  
161         /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送  
162         /// </remarks>  
163         public int SendData(Socket socket, string buffer, int outTime)
164         {
165             if (buffer == null || buffer.Length == 0)
166             {
167                 throw new ArgumentException("待发送的字符串长度不能为零.");
168             }
169             return (SendData(socket, System.Text.Encoding.Default.GetBytes(buffer), outTime));
170         }
171 
172 
173         /**/
174         /// <summary>  
175         /// 接收远程主机发送的数据  
176         /// </summary>  
177         /// <param name="socket">要接收数据且已经连接到远程主机的 socket</param>  
178         /// <param name="buffer">接收数据的缓冲区</param>  
179         /// <param name="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>  
180         /// <returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>  
181         /// <remarks >  
182         /// 1、当 outTime 指定为-1时,将一直等待直到有数据需要接收;  
183         /// 2、需要接收的数据的长度,由 buffer 的长度决定。  
184         /// </remarks>  
185         public int RecvData(Socket socket, byte[] buffer, int outTime)
186         {
187             if (socket == null || socket.Connected == false)
188             {
189                 throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
190             }
191             if (buffer == null || buffer.Length == 0)
192             {
193                 throw new ArgumentException("参数buffer 为null ,或者长度为 0");
194             }
195             buffer.Initialize();
196             int left = buffer.Length;
197             int curRcv = 0;
198             int flag = 0;
199 
200             try
201             {
202                 while (true)
203                 {
204                     if (socket.Poll(outTime * 1000000, SelectMode.SelectRead) == true)
205                     {        // 已经有数据等待接收  
206                         curRcv = socket.Receive(buffer, curRcv, left, SocketFlags.None);
207                         left -= curRcv;
208                         if (left == 0)
209                         {                                    // 数据已经全部接收   
210                             flag = 0;
211                             break;
212                         }
213                         else
214                         {
215                             if (curRcv > 0)
216                             {                                // 数据已经部分接收  
217                                 continue;
218                             }
219                             else
220                             {                                            // 出现错误  
221                                 flag = -2;
222                                 break;
223                             }
224                         }
225                     }
226                     else
227                     {                                                    // 超时退出  
228                         flag = -1;
229                         break;
230                     }
231                 }
232             }
233             catch (SocketException e)
234             {
235                 //Log.WriteLog ( e );  
236                 flag = -3;
237             }
238             return flag;
239         }
240 
241         /**/
242         /// <summary>  
243         /// 接收远程主机发送的数据  
244         /// </summary>  
245         /// <param name="socket">要接收数据且已经连接到远程主机的 socket</param>  
246         /// <param name="buffer">存储接收到的数据的字符串</param>  
247         /// <param name="bufferLen">待接收的数据的长度</param>  
248         /// <param name="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>  
249         /// <returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>  
250         /// <remarks >  
251         /// 当 outTime 指定为-1时,将一直等待直到有数据需要接收;  
252         /// </remarks>  
253         public int RecvData(Socket socket, string buffer, int bufferLen, int outTime)
254         {
255             if (bufferLen <= 0)
256             {
257                 throw new ArgumentException("存储待接收数据的缓冲区长度必须大于0");
258             }
259             byte[] tmp = new byte[bufferLen];
260             int flag = 0;
261             if ((flag = RecvData(socket, tmp, outTime)) == 0)
262             {
263                 buffer = System.Text.Encoding.Default.GetString(tmp);
264             }
265             return flag;
266         }
267 
268 
269         /**/
270         /// <summary>  
271         /// 向远程主机发送文件  
272         /// </summary>  
273         /// <param name="socket" >要发送数据且已经连接到远程主机的 socket</param>  
274         /// <param name="fileName">待发送的文件名称</param>  
275         /// <param name="maxBufferLength">文件发送时的缓冲区大小</param>  
276         /// <param name="outTime">发送缓冲区中的数据的超时时间</param>  
277         /// <returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>  
278         /// <remarks >  
279         /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送  
280         /// </remarks>  
281         public int SendFile(Socket socket, string fileName, int maxBufferLength, int outTime)
282         {
283             if (fileName == null || maxBufferLength <= 0)
284             {
285                 throw new ArgumentException("待发送的文件名称为空或发送缓冲区的大小设置不正确.");
286             }
287 
288             int flag = 0;
289             try
290             {
291                 FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
292                 long fileLen = fs.Length;                        // 文件长度  
293                 long leftLen = fileLen;                            // 未读取部分  
294                 int readLen = 0;                                // 已读取部分  
295                 byte[] buffer = null;
296 
297                 if (fileLen <= maxBufferLength)
298                 {            /**//* 文件可以一次读取*/
299                     buffer = new byte[fileLen];
300                     readLen = fs.Read(buffer, 0, (int)fileLen);
301                     flag = SendData(socket, buffer, outTime);
302                 }
303                 else
304                 {                                    /**//* 循环读取文件,并发送 */
305                     buffer = new byte[maxBufferLength];
306                     while (leftLen != 0)
307                     {
308                         readLen = fs.Read(buffer, 0, maxBufferLength);
309                         if ((flag = SendData(socket, buffer, outTime)) < 0)
310                         {
311                             break;
312                         }
313                         leftLen -= readLen;
314                     }
315                 }
316                 fs.Close();
317             }
318             catch (IOException e)
319             {
320                 //Log.WriteLog ( e );  
321                 flag = -4;
322             }
323             return flag;
324         }
325 
326         /**/
327         /// <summary>  
328         /// 向远程主机发送文件  
329         /// </summary>  
330         /// <param name="socket" >要发送数据且已经连接到远程主机的 socket</param>  
331         /// <param name="fileName">待发送的文件名称</param>  
332         /// <returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>  
333         public int SendFile(Socket socket, string fileName)
334         {
335             return SendFile(socket, fileName, 2048, 1);
336         }
337 
338 
339         /**/
340         /// <summary>  
341         /// 接收远程主机发送的文件  
342         /// </summary>  
343         /// <param name="socket">待接收数据且已经连接到远程主机的 socket</param>  
344         /// <param name="fileName">保存接收到的数据的文件名</param>  
345         /// <param name="fileLength" >待接收的文件的长度</param>  
346         /// <param name="maxBufferLength">接收文件时最大的缓冲区大小</param>  
347         /// <param name="outTime">接受缓冲区数据的超时时间</param>  
348         /// <returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>  
349         /// <remarks >  
350         /// 当 outTime 指定为-1时,将一直等待直到有数据需要接收  
351         /// </remarks>  
352         public int RecvFile(Socket socket, string fileName, long fileLength, int maxBufferLength, int outTime)
353         {
354             if (fileName == null || maxBufferLength <= 0)
355             {
356                 throw new ArgumentException("保存接收数据的文件名称为空或发送缓冲区的大小设置不正确.");
357             }
358 
359             int flag = 0;
360             try
361             {
362                 FileStream fs = new FileStream(fileName, FileMode.Create);
363                 byte[] buffer = null;
364 
365                 if (fileLength <= maxBufferLength)
366                 {                /**//* 一次读取所传送的文件 */
367                     buffer = new byte[fileLength];
368                     if ((flag = RecvData(socket, buffer, outTime)) == 0)
369                     {
370                         fs.Write(buffer, 0, (int)fileLength);
371                     }
372                 }
373                 else
374                 {                                        /**//* 循环读取网络数据,并写入文件 */
375                     int rcvLen = maxBufferLength;
376                     long leftLen = fileLength;                        //剩下未写入的数据  
377                     buffer = new byte[rcvLen];
378 
379                     while (leftLen != 0)
380                     {
381                         if ((flag = RecvData(socket, buffer, outTime)) < 0)
382                         {
383                             break;
384                         }
385                         fs.Write(buffer, 0, rcvLen);
386                         leftLen -= rcvLen;
387                         rcvLen = (maxBufferLength < leftLen) ? maxBufferLength : ((int)leftLen);
388                     }
389                 }
390                 fs.Close();
391             }
392             catch (IOException e)
393             {
394                 //Log.WriteLog ( e );  
395                 flag = -4;
396             }
397             return flag;
398         }
399 
400         /**/
401         /// <summary>  
402         /// 接收远程主机发送的文件  
403         /// </summary>  
404         /// <param name="socket">待接收数据且已经连接到远程主机的 socket</param>  
405         /// <param name="fileName">保存接收到的数据的文件名</param>  
406         /// <param name="fileLength" >待接收的文件的长度</param>  
407         /// <returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>  
408         public int RecvFile(Socket socket, string fileName, long fileLength)
409         {
410             return RecvFile(socket, fileName, fileLength, 2048, 1);
411         }
412 
413         //public static int SendAndReceive(Socket socket, string strCmd, out string strBuffer, TimeSpan timeout)
414         //{
415         //    try
416         //    {
417         //        return 0;
418         //    }
419         //    catch (Exception ex)
420         //    {
421         //        return -1;
422         //    }
423         //}
424 
425         public bool SendCmd(Socket socket, string strCmd, out string strErrorInfo)
426         {
427             strErrorInfo = string.Empty;
428             byte[] byteCmd;
429             //int flag = 0;
430             int left = 0;
431             int sndLen = 0;
432             int outTime = 60;
433 
434             try
435             {
436                 if (null == socket || !socket.Connected)
437                 {
438                     strErrorInfo = "socket is null or unconnected.";
439                     return false;
440                 }
441 
442                 if (string.IsNullOrEmpty(strCmd))
443                 {
444                     strErrorInfo = "Cmd is null or empty.";
445                     return false;
446                 }
447 
448                 byteCmd = Encoding.UTF8.GetBytes(strCmd);
449                 left = byteCmd.Length;
450                 while (true)
451                 {
452                     if ((socket.Poll(outTime * 1000000, SelectMode.SelectWrite) == true))
453                     {        // 收集了足够多的传出数据后开始发送  
454                         sndLen = socket.Send(byteCmd, sndLen, left, SocketFlags.None);
455                         left -= sndLen;
456                         if (left == 0)
457                         {                                        // 数据已经全部发送  
458                             //flag = 0;
459                             break;
460                         }
461                         else
462                         {
463                             if (sndLen > 0)
464                             {                                    // 数据部分已经被发送  
465                                 continue;
466                             }
467                             else
468                             {                                                // 发送数据发生错误  
469                                 //flag = -2;
470                                 //break;
471                                 strErrorInfo = "Send cmd error.";
472                                 return false;
473                             }
474                         }
475                     }
476                     else
477                     {                                                        // 超时退出  
478                         //flag = -1;
479                         //break;
480                         strErrorInfo = "Send cmd timeout.";
481                         return false;
482                     }
483                 }
484 
485                 Global.frmAUACOSS.Invoke(Global.frmAUACOSS.updateRTxt, Global.frmAUACOSS.rtxtDEBUG, PrintLevel.Zero, "发送报文:\n" + strCmd + "\n\n", Color.Black, true);
486 
487                 return true;
488 
489             }
490             catch (Exception ex)
491             {
492                 strErrorInfo = "Send cmd occurs Ex: " + ex.ToString();
493                 return false;
494             }
495         }
496 
497         public bool WaitReply(Socket socket, string strWaitString, out string strBuffer, TimeSpan timeout, out string strErrorInfo)
498         {
499             strBuffer = string.Empty;
500             string strBufferTemp = string.Empty;
501             strErrorInfo = string.Empty;
502             int bufferLen = 10240;
503             byte[] tmp = new byte[bufferLen];
504             int left = 0;
505             int curRcv = 0;
506             //int flag = 0;
507 
508             bool IsContainWaitString = false;
509 
510             try
511             {
512                 if (null == socket || !socket.Connected)
513                 {
514                     strErrorInfo = "socket is null or unconnected.";
515                     return false;
516                 }
517 
518                 tmp.Initialize();
519                 left = tmp.Length;
520                 strBuffer = strBufferLeft;
521 
522                 while (true)
523                 {
524                     if (socket.Poll((int)timeout.TotalSeconds * 1000000, SelectMode.SelectRead) == true)
525                     {        // 已经有数据等待接收  
526                         //    curRcv = socket.Receive(tmp, curRcv, left, SocketFlags.None);
527                         //    left -= curRcv;
528                         //    if (left == 0)
529                         //    {                                    // 数据已经全部接收   
530                         //        //flag = 0;
531                         //        break;
532                         //    }
533                         //    else
534                         //    {
535                         //        if (curRcv > 0)
536                         //        {                                // 数据已经部分接收  
537                         //            continue;
538                         //        }
539                         //        else
540                         //        {                                            // 出现错误  
541                         //            //flag = -2;
542                         //            strErrorInfo = "Receive buffer error.";
543                         //            break;
544                         //        }
545                         //    }
546 
547                         curRcv = socket.Receive(tmp, curRcv, left, SocketFlags.None);
548 
549                         strBufferTemp = Encoding.UTF8.GetString(tmp);
550 
551                         strBuffer = strBuffer.Trim('\0');
552 
553                         strBuffer += strBufferTemp;
554 
555                         foreach (string strWaitStringTemp in strWaitString.Split('|'))
556                         {
557                             if (strBuffer.Contains(strWaitStringTemp))
558                             {
559                                 IsContainWaitString = true;
560                                 break;
561                             }
562                         }
563                         if (IsContainWaitString)
564                         {
565                             strBufferLeft = strBuffer.Substring(strBuffer.IndexOf(strWaitString) + strWaitString.Length);
566                             strBuffer = strBuffer.Substring(0, strBuffer.IndexOf(strWaitString) + strWaitString.Length);
567                             break;
568                         }
569                     }
570                     else
571                     {                                                    // 超时退出  
572                         //flag = -1;
573                         strErrorInfo = "Receive buffer timeout.";
574                         return false;
575                     }
576                 }
577 
578                 Global.frmAUACOSS.Invoke(Global.frmAUACOSS.updateRTxt, Global.frmAUACOSS.rtxtDEBUG, PrintLevel.Zero, "接收报文:\n" + strBuffer + "\n\n", Color.Black, true);
579 
580                 return true;
581             }
582             catch (Exception ex)
583             {
584                 strErrorInfo = "Wait reply occurs Ex: " + ex.ToString();
585                 return false;
586             }
587         }
588     }
View Code

猜你喜欢

转载自www.cnblogs.com/linyu168/p/9302204.html