zoukankan      html  css  js  c++  java
  • C# 多线程网络通信

      

     博客园 :梦工厂2012   

      本月由于事情太多,没能有太多的时间去写博客.不过还好在月底抽时间写了这个多线程网络通信的程序 .程序说明:控制端 创建一个写线程threadWrite和一个读线程threadRead  ,写线程用于向控制端发送操控指令.读线程用于读取被控制端姿态数据.这里C# 编写了一个模拟被控端ServerConsole .源代码如下,

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Net.Sockets;
      6 using System.Net;
      7 using System.Timers;
      8 using System.Threading;
      9 
     10 namespace ServerConsole
     11 {
     12     class Program
     13     {
     14         //创建写线程
     15             private static Thread threadWrite;
     16             static int send_num = 0; 
     17             static NetworkStream streamToClient, streamFromClient;
     18 
     19             static void Main(string[] args)
     20             {
     21                 ushort[] data=new ushort[4];
     22                 const int BufferSize = 10;
     23                 int received_num = 0;  
     24                 byte[] buffer = new byte[BufferSize];
     25                 int bytesRead;
     26                 Console.WriteLine("Server is runing");
     27 
     28                 IPAddress ip = new IPAddress(new byte[]{192,168,0,1});
     29                 TcpListener listener = new TcpListener(ip, 8500);
     30 
     31                 listener.Start();
     32                 Console.WriteLine("Start listening");          
     33                 while(true)
     34                 {
     35                     //为TCP网络服务提供提供客户端连接
     36                     TcpClient remoteClient = listener.AcceptTcpClient();    //Receive the request of connection
     37                     // 打印连接到的客户端信息
     38                     Console.WriteLine("Client Connected!{0} <-- {1}", remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);
     39                     streamToClient = remoteClient.GetStream();
     40                     streamFromClient = remoteClient.GetStream();
     41                     
     42                     /*--------------------------------Creat the write thread----------------------------------------*/
     43                     threadWrite = new Thread(new ThreadStart(write));
     44                     Console.WriteLine("实例化线程");
     45                   
     46                     /*-------------------------------------------------------------------------------------------------*/
     47                     Handshaking();  //Hand shake  ,与上位机进行握手
     48                     
     49                      while(true)
     50                     {
     51                        
     52                         try
     53                         {           
     54                             bytesRead = streamFromClient.Read(buffer, 0, BufferSize);
     55                             received_num++;
     56                             if (bytesRead == 0) throw new Exception("读取到0字节");
     57 
     58                             Console.WriteLine("Reading data,{0}bytes...", bytesRead);
     59 
     60                             ushort temp = checksum(buffer, 8);
     61                             if (temp == ((ushort)buffer[8] + (ushort)(buffer[9] << 8)))
     62                             {
     63                                 Console.WriteLine("校验正确");
     64                                 data[0] = (ushort)(buffer[0] + (buffer[1] << 8));
     65                                 data[1] = (ushort)(buffer[2] + (buffer[3] << 8));
     66                                 data[2] = (ushort)(buffer[4] + (buffer[5] << 8));
     67                                 data[3] = (ushort)(buffer[6] + (buffer[7] << 8));
     68                                 Console.WriteLine("The result is {0},{1},{2},{3},接收{4},发送{5}.", data[0], data[1], data[2], data[3],received_num,send_num);
     69                             }
     70                             else
     71                                 Console.WriteLine("校验不正确!");
     72   
     73                         
     74                         }
     75                         catch (Exception ex)
     76                         {
     77                             Console.WriteLine(ex.Message);
     78                             break;
     79                         }
     80                      } //while
     81 
     82                     Console.WriteLine("
    输入Q键退出,其他键继续!");             
     83                     ConsoleKey key;
     84                     
     85                     key = Console.ReadKey(true).Key;
     86                     if (key == ConsoleKey.Q)
     87                         return;
     88                     else
     89                     {
     90                         Console.WriteLine("continute....");
     91                         received_num = 0;
     92                         send_num = 0;
     93                     }
     94                 }   //whlie   
     95             }  //main
     96 
     97 
     98 
     99         private static void write()
    100         {
    101             byte[] send_byte = new byte[18];
    102             while (true)
    103             {
    104                 for (int i = 0; i < 16;i++ )
    105                 {
    106                     send_byte[i] = (byte)2;
    107                 }
    108                 ushort temp = checksum(send_byte, 16);
    109                 send_byte[16] = (byte)(temp & 0x00ff);                           //low
    110                 send_byte[17] = (byte)((temp & 0xff00) >> 8);           //high
    111                 //下面进行数据的发送......
    112                 try
    113                 {
    114                     streamToClient.Write(send_byte, 0, send_byte.Length);      // 发往客户端
    115                     send_num++;
    116                 }
    117                 catch (Exception x)
    118                 {
    119                     Console.WriteLine(x.Message);
    120                     return;
    121                 }
    122                 Thread.Sleep(20);
    123             }
    124         }
    125 
    126 
    127         /// <summary>
    128         /// 与 上位机进行握手
    129         /// </summary>
    130         private static void Handshaking()
    131         {
    132             byte[] buffer = new byte[1];
    133             lock (streamFromClient)
    134             {
    135                 int bytesRead = streamFromClient.Read(buffer, 0, 1);
    136                 Console.WriteLine("Reading data,{0}bytes...", bytesRead);
    137             }
    138             if (buffer[0] == 0x41)
    139             {
    140                 Console.WriteLine("Received: {0}", Encoding.ASCII.GetString(buffer, 0, buffer.Length));
    141                 buffer[0] = 0x42;
    142                 lock (streamToClient)
    143                 {
    144                     streamToClient.Write(buffer, 0, buffer.Length);
    145                 }
    146                 Console.WriteLine("sent;{0}", Encoding.ASCII.GetString(buffer, 0, buffer.Length));
    147 
    148                 if(!threadWrite.IsAlive)
    149                 {
    150                     threadWrite.Start();  
    151                     Console.WriteLine("start the write thread ");
    152                 }
    153                 
    154             }
    155         }
    156 
    157 
    158         /// <summary>
    159         /// CRC16校验函数
    160         /// </summary>
    161         /// <param name="array"></param>
    162         /// <param name="Len"></param>
    163         /// <returns></returns>
    164             private static ushort CRC16(char[] array, int Len)
    165             {
    166                 int CRC;
    167                 UInt16 IX, IY;
    168                 CRC = 0xffff;   //set all 1
    169                 for (IX = 0; IX < Len; IX++)
    170                 {
    171 
    172                     CRC = CRC ^ (UInt16)(array[IX]);
    173                     for (IY = 0; IY <= 7; IY++)
    174                     {
    175                         if ((CRC & 1) != 0)
    176                             CRC = (CRC >> 1) ^ 0xA001;
    177                         else
    178                             CRC = CRC >> 1;
    179                     }
    180 
    181                 }
    182                 return (ushort)CRC;
    183             }
    184 
    185             //checksum校验
    186             private static ushort checksum(byte[] array, int Len)
    187             {
    188                 ushort check_sum = 0, i;
    189                 //char temp[8];
    190                 for (i = 0; i < Len; i += 2)
    191                 {
    192                     check_sum += (ushort)((array[i + 1] << 8) + array[i]);
    193                 }
    194                 return check_sum;
    195             }
    196   
    197 
    198 
    199     }
    200 }

    代码简介:代码写的用点乱,大家将就看吧.  主程序用于接收 控制数据  ,如外我创建一个写线程用于向控制端数据.这里收到的数据我全部写为 (byte)1,发送的数据全部写为(byte)2  ,校验采用累加和校验 .被控端与操控端采用0x41  0x42 进行简单的握手,其实感觉是有点多于了.操控端与被控端没有太大的区别,数据通信部分是相同的,创建连接的代码有点不同.  

    基本过程:

    //实例化通信类
    TcpClient client = new TcpClient();

     client.Connect(url_conrtol, Convert.ToInt32(portNumber));      // 与服务器连接  

      streamToServer = client.GetStream();

    读写过程 与上面帖的代码相同. 

      在程序编写过程中,我使用多线程和networkstream 的read,write对流的读写,因为是单机点对点通信并没有发现有什么问题(read 阻塞 ,write 不阻塞 ),read 阻塞不影响发送 . 网上有资料说: Write 和 Read 方法用于简单的单线程同步阻止 I/O。若要使用不同的线程来处理 I/O,则请考虑使用BeginWrite 和 EndWrite 方法,或 BeginRead 和 EndRead 方法进行通信。程序中用用于lock关键字,具体是否起到作用,本人仍在查找资料.

    每个程序都是本人花费一定的时间经过多次修改所得,直到程序最优,有些看似简单的问题其实一点也不简单!!博文为本人所写转载请表明出处C# 多线程网络通信

  • 相关阅读:
    IDEA2019.1.2破解教程
    Java基础 -- 常见异常
    Java基础 -- Java基本类(部分)
    Java基础 -- IO流
    Java基础 -- Java方法
    Java数组
    IDEA首次配置问题
    Java开发环境搭建
    dos的几种打开方式和基本dos命令
    SpringBoot内外部配置文件加载和优先级
  • 原文地址:https://www.cnblogs.com/dreamfactory/p/3162420.html
Copyright © 2011-2022 走看看