博客园 :梦工厂2012   

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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Timers;
using System.Threading; namespace ServerConsole
{
class Program
{
//创建写线程
private static Thread threadWrite;
static int send_num = ;
static NetworkStream streamToClient, streamFromClient; static void Main(string[] args)
{
ushort[] data=new ushort[];
const int BufferSize = ;
int received_num = ;
byte[] buffer = new byte[BufferSize];
int bytesRead;
Console.WriteLine("Server is runing"); IPAddress ip = new IPAddress(new byte[]{,,,});
TcpListener listener = new TcpListener(ip, ); listener.Start();
Console.WriteLine("Start listening");
while(true)
{
//为TCP网络服务提供提供客户端连接
TcpClient remoteClient = listener.AcceptTcpClient(); //Receive the request of connection
// 打印连接到的客户端信息
Console.WriteLine("Client Connected!{0} <-- {1}", remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);
streamToClient = remoteClient.GetStream();
streamFromClient = remoteClient.GetStream(); /*--------------------------------Creat the write thread----------------------------------------*/
threadWrite = new Thread(new ThreadStart(write));
Console.WriteLine("实例化线程"); /*-------------------------------------------------------------------------------------------------*/
Handshaking(); //Hand shake ,与上位机进行握手 while(true)
{ try
{
bytesRead = streamFromClient.Read(buffer, , BufferSize);
received_num++;
if (bytesRead == ) throw new Exception("读取到0字节"); Console.WriteLine("Reading data,{0}bytes...", bytesRead); ushort temp = checksum(buffer, );
if (temp == ((ushort)buffer[] + (ushort)(buffer[] << )))
{
Console.WriteLine("校验正确");
data[] = (ushort)(buffer[] + (buffer[] << ));
data[] = (ushort)(buffer[] + (buffer[] << ));
data[] = (ushort)(buffer[] + (buffer[] << ));
data[] = (ushort)(buffer[] + (buffer[] << ));
Console.WriteLine("The result is {0},{1},{2},{3},接收{4},发送{5}.", data[], data[], data[], data[],received_num,send_num);
}
else
Console.WriteLine("校验不正确!"); }
catch (Exception ex)
{
Console.WriteLine(ex.Message);
break;
}
} //while Console.WriteLine("\n输入Q键退出,其他键继续!");
ConsoleKey key; key = Console.ReadKey(true).Key;
if (key == ConsoleKey.Q)
return;
else
{
Console.WriteLine("continute....");
received_num = ;
send_num = ;
}
} //whlie
} //main private static void write()
{
byte[] send_byte = new byte[];
while (true)
{
for (int i = ; i < ;i++ )
{
send_byte[i] = (byte);
}
ushort temp = checksum(send_byte, );
send_byte[] = (byte)(temp & 0x00ff); //low
send_byte[] = (byte)((temp & 0xff00) >> ); //high
//下面进行数据的发送......
try
{
streamToClient.Write(send_byte, , send_byte.Length); // 发往客户端
send_num++;
}
catch (Exception x)
{
Console.WriteLine(x.Message);
return;
}
Thread.Sleep();
}
} /// <summary>
/// 与 上位机进行握手
/// </summary>
private static void Handshaking()
{
byte[] buffer = new byte[];
lock (streamFromClient)
{
int bytesRead = streamFromClient.Read(buffer, , );
Console.WriteLine("Reading data,{0}bytes...", bytesRead);
}
if (buffer[] == 0x41)
{
Console.WriteLine("Received: {0}", Encoding.ASCII.GetString(buffer, , buffer.Length));
buffer[] = 0x42;
lock (streamToClient)
{
streamToClient.Write(buffer, , buffer.Length);
}
Console.WriteLine("sent;{0}", Encoding.ASCII.GetString(buffer, , buffer.Length)); if(!threadWrite.IsAlive)
{
threadWrite.Start();
Console.WriteLine("start the write thread ");
} }
} /// <summary>
/// CRC16校验函数
/// </summary>
/// <param name="array"></param>
/// <param name="Len"></param>
/// <returns></returns>
private static ushort CRC16(char[] array, int Len)
{
int CRC;
UInt16 IX, IY;
CRC = 0xffff; //set all 1
for (IX = ; IX < Len; IX++)
{ CRC = CRC ^ (UInt16)(array[IX]);
for (IY = ; IY <= ; IY++)
{
if ((CRC & ) != )
CRC = (CRC >> ) ^ 0xA001;
else
CRC = CRC >> ;
} }
return (ushort)CRC;
} //checksum校验
private static ushort checksum(byte[] array, int Len)
{
ushort check_sum = , i;
//char temp[8];
for (i = ; i < Len; i += )
{
check_sum += (ushort)((array[i + ] << ) + array[i]);
}
return check_sum;
} }
}

代码简介:代码写的用点乱,大家将就看吧.  主程序用于接收 控制数据  ,如外我创建一个写线程用于向控制端数据.这里收到的数据我全部写为 (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# 多线程网络通信

C# 多线程网络通信的更多相关文章

  1. 深入浅出Win32多线程程序设计之基本概念

    一.深入浅出Win32多线程程序设计之基本概念[转] 引言 从单进程单线程到多进程多线程是操作系统发展的一种必然趋势,当年的DOS系统属于单任务操作系统,最优秀的程序员也只能通过驻留内存的方式实现所谓 ...

  2. python-网络编程-socket编程

    一.TCP\IP(网络通信协议)简介       TCP:(Transmission Control Protocol)传输控制协议,面向有连接的通信协议  UDP:数据报文协议,面向无连接的通信协议 ...

  3. JAVA基础知识复习小结

    集合 Set集合 Set集合的基本特征是元素不允许重复.HashSet不保存元素顺序,LinkedHashSet用链表保持元素的插入顺序,TreeSet可定制排序规则. HashSet的底层是用Has ...

  4. odoo 8.0 多核启用

    对于很多企业来说,随着时间的推移,用户量或者企业建点扩张,使用erp就会出现应用访问越来越慢的情况, 其实这种情况不但限于erp,只要是有数据量增长的互联网业务必然会遇到的,因为一开始的是就没有做好大 ...

  5. Ptypes一个开源轻量级的c++库,包括对一些I/O操作、网络通信、多线程和异常处理的封装

    C++开源项目入门级:Ptypes    Ptypes一个开源轻量级的c++库,包括对一些I/O操作.网络通信.多线程和异常处理的封装.虽然代码有限,包括的内容不少,麻雀虽小,五脏俱全.    提高: ...

  6. Linux网络通信(TCP套接字编写,多进程多线程版本)

    预备知识 源IP地址和目的IP地址 IP地址在上一篇博客中也介绍过,它是用来标识网络中不同主机的地址.两台主机进行通信时,发送方需要知道自己往哪一台主机发送,这就需要知道接受方主机的的IP地址,也就是 ...

  7. 以libevent网络库为引:网络通信和多线程

    1. windows下编译及使用libevent  http://www.cnblogs.com/luxiaoxun/p/3603399.html 2.  <<libevent学习资料&g ...

  8. Linux下C语言多线程,网络通信简单聊天程序

    http://www.cnblogs.com/zhuxianji/archive/2011/01/06/1928970.html

  9. Linux下使用多线程模拟异步网络通信

    服务器 /* socket server * 2014-12-15 CopyRight (c) arbboter */ #include <unistd.h> #include <s ...

随机推荐

  1. map遍历的四种方法

    public static void main(String[] args) { Map<String, String> map = new HashMap<String, Stri ...

  2. PHP设置图片文件上传大小的具体实现方法

    PHP默认的上传限定是最大2M,想上传超过此设定的文件,需要调整PHP.apache等的一些参数 我们简要介绍一下PHP文件上传涉及到的一些参数: •file_uploads :是否允许通过HTTP上 ...

  3. hdu5443(2015长春赛区网络赛1007)暴力

    题意:给了一个数列,有多个询问,每个询问求某个区间内的最大值 数列长度 1000,询问个数 1000,静态,并不需要RMQ这些,直接暴力 n2 查找每个询问区间取最大值就行了. #include< ...

  4. PHP的一些要点

    1.用户评论的内容应当使用htmlspecialchars()函数进行过滤,如htmlspecialchars($_POST['content']);再写入数据库,防止用户评论中含有JS和HTML代码 ...

  5. ABB机器人添加串口模块后无法使用的解决办法

    [环境] ABB机器人1520,IRC5,RobotWare5.6,Win10 64bits,RobotStudio6.0 [过程和表现] 由于项目需要和机器人通信,DeviceNet又不能满足要求, ...

  6. ps通道混合器

    输出通道:红 ,加绿变黄,加蓝变品红,减红变青.输出通道:绿,加红变黄,加蓝变青,减绿变品红.输出通道:蓝,加红变品红,加绿变青,减蓝变黄[对比色]

  7. sql commands

    1,DBCC SQLPERF(logspace) https://msdn.microsoft.com/en-us/library/ms189768.aspx 2, 1, LOGINFO(''HAHA ...

  8. MFC开发上位机到底用Dialog结构还是文档结构?

    最近要跟着导师一起开发一款大型上位机.MFC新人在考虑用对话框结构还是文档结构. 虽然说书上说大型结构的软件都需要文档结构,但是目前来看,对话框可以实现功能,并且对话框的程序更小一些,节省资源加载速度 ...

  9. H2 database 行相加-行列转换

    create or replace view view_acceptCompanyasselect *  from  (select WARNIGID,max(CASEWHEN(zhtablename ...

  10. Unity3D研究院之Android同步方法读取streamingAssets

    版本Unity5.3.3 Android 小米pad1 首先非常感谢 @守着阳光 同学在下面的留言.让我解决了一个大的谜团.. 开始我知道 StreamingAssets 路径是这个 path = & ...