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 }