博客园 :梦工厂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. 前后台Json的转换

    jsp:JSON.stringify(params):params:表示数组 servlet:Store store = (Store) JSONObject.toBean(JSONObject.fr ...

  2. 转:bash: /dev/null: Permission denied

    普通用户登录:bash: /dev/null: Permission denied 2012-12-07 16:01:36|  分类: linux |举报 |字号 订阅     Last login: ...

  3. 通过joystick遥感和按键控制机器人--11

    原创博客:转载请表明出处:http://www.cnblogs.com/zxouxuewei/ 1.首先安装joystick遥控器驱动: sudo apt-get install ros-indigo ...

  4. 工作中遇到的问题--Hibernate一对多保存简化Service层代码

    在创建一方的entity是添加一个增加多方的方法: package com.sim.mfg.data.domain; import java.io.Serializable;import java.u ...

  5. 4-2 光盘yum源搭建

    yum源默认是用网络作为yum源,在一些特殊情况下,比如教学.实验室等,不是所有的环境都可以联网 这种不能使用网络的情况下,可以使用光盘搭建yum源 我们知道,光盘包含了所有的rpm包,因此使用光盘搭 ...

  6. DELPHI相应鼠标滚轮

    在鼠标的MouseWheel事件里写入以下内容 if WheelDelta < 0 then    SendMessage(scrollBox1.Handle, WM_VSCROLL, SB_L ...

  7. kuangbin_MST A (POJ 1251)

    模板题 Kruskal直接过 调试时候居然在sort(edge + 1, edge + 1 + m)上浪费好多时间... 不过本着ACMer的心态自然要测试一下两种方法分别的速度 Kruskal : ...

  8. Unity Shaders

    推荐!! Unity技术人员的博客: http://aras-p.info/blog/ Unity 中的 Shader 按照使用方式来分的话,分为3种: Surface Shader 受光照影响 Cg ...

  9. 此博客记录我的进阶之路(PHP、C、Python、Erlang)

    强大自己!赚钱,装修,娶媳妇!!

  10. docker镜像、容器

    第一部分:Docker镜像的基本知识 1.1 什么是Docker镜像 从整体的角度来讲,一个完整的Docker镜像可以支撑一个Docker容器的运行,在 Docker容器运行过程中主要提供文件系统视角 ...