TCPIP通信
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Linq;
using System.Net.NetworkInformation; namespace HY_RFID
{
public class MyTCPServer
{
public bool isExit = false;
private TcpListener listener;
public TcpClient readClient;
List<ReadWriteObject> rws = new List<ReadWriteObject>();
public List<TCPIP> ips = new List<TCPIP>(); #region 创建事件
//声明事件参数
public class TcpClientArgs : EventArgs
{
public readonly TcpClient client;
public TcpClientArgs(TcpClient client)
{
this.client = client;
}
}
public class BackMsgArgs : EventArgs
{
public readonly string backMsg;
public BackMsgArgs(string backMsg)
{
this.backMsg = backMsg;
}
}
public class BackByteArgs : EventArgs
{
public readonly byte[] backByte;
public BackByteArgs(byte[] backByte)
{
this.backByte = backByte;
}
}
public delegate void WaitConnectEventHandler(object sender,EventArgs e);
public event WaitConnectEventHandler OnWaitConnect;
protected virtual void WaitConnect()
{
if (OnWaitConnect != null)// 如果有对象注册
{
OnWaitConnect(this, null);// 调用所有注册对象的方法
}
}
//声明委托
public delegate void SuccessConnectEventHandler(object sender, TcpClientArgs e);
//声明事件
public event SuccessConnectEventHandler OnSuccessConnect;
//触发方法
protected virtual void SuccessConnect(TcpClientArgs e)
{
if (OnSuccessConnect != null)// 如果有对象注册
{
OnSuccessConnect(this, e);// 调用所有注册对象的方法
}
}
public delegate void ReadCallBackMsgEventHandler(object sender, BackByteArgs e);
public event ReadCallBackMsgEventHandler OnReadCallBack;
protected virtual void ReadCallBackMsg(BackByteArgs e)
{
if (OnReadCallBack != null)// 如果有对象注册
{
OnReadCallBack(this, e);// 调用所有注册对象的方法
}
}
public delegate void ReadErrorCallBackMsgEventHandler(object sender, BackMsgArgs e);
public event ReadErrorCallBackMsgEventHandler OnReadErrorCallBack;
protected virtual void ReadErrorCallBackMsg(BackMsgArgs e)
{
if (OnReadErrorCallBack != null)// 如果有对象注册
{
OnReadErrorCallBack(this, e);// 调用所有注册对象的方法
}
}
#endregion //用于线程同步,初始状态设为非终止状态,使用手动重置方式
private EventWaitHandle allDone = new EventWaitHandle(false, EventResetMode.ManualReset);
//服务端监听方法
public void ServerListen(int port)
{
//由于服务器要为多个客户服务,所以需要创建一个线程监听客户端连接请求
isExit = false;
if (!PortInUse(port))
{
Thread myThread = new Thread(new ParameterizedThreadStart(AcceptConnect));
myThread.Start(port);
}
else
{
throw new Exception("当前端口已被占用!");
}
}
/// <summary>
/// 检测但钱端口是否被占用
/// </summary>
/// <param name="port"></param>
/// <returns></returns>
private bool PortInUse(int port)
{
bool inUse = false;
//获取所有的监听连接
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
foreach (IPEndPoint endPoint in ipEndPoints)
{
if (endPoint.Port == port)
{
inUse = true;
break;
}
}
return inUse;
}
//与客户机取得连接
private void AcceptConnect(object o)
{
try
{
if (o == null) return;
IPAddress ip4 = GetLocalIpv4() as IPAddress;
listener = new TcpListener(ip4, Convert.ToInt32(o));
listener.Start();
//引用在异步操作完成时调用的回调方法
AsyncCallback callback = new AsyncCallback(AcceptTcpClientCallback);
while (!isExit)
{ //将事件的状态设为非终止
allDone.Reset();
//触发等待事件
WaitConnect();
//开始一个异步操作接受传入的连接尝试
listener.BeginAcceptTcpClient(callback, listener);
//阻塞当前线程,直到收到客户连接信号
allDone.WaitOne();
Thread.Sleep();
}
}
catch (Exception ex)
{
throw ex;
}
}
//获取本机IP
public object GetLocalIpv4()
{
//获取本机所有IP地址
try
{
IPAddress[] localips = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress ip in localips)
{
//找到本地所有IP地址符合IPV4协议的IP地址
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip;
}
}
}
catch (Exception ex)
{
throw ex;
}
return null;
}
// 连接客户端的回调函数
//ar是IAsyncResult类型的接口,表示异步操作的状态是由listener.BeginAcceptTcpClient(callback, listener)传递过来的
private void AcceptTcpClientCallback(IAsyncResult ar)
{
lock (this)
{
try
{
if (isExit) return;
//将事件状态设为终止状态,允许一个或多个等待线程继续
allDone.Set();
TcpListener myListener = (TcpListener)ar.AsyncState;
//异步接收传入的连接,并创建新的TcpClient对象处理远程主机通信
TcpClient client = myListener.EndAcceptTcpClient(ar);
//已接受客户连接
TcpClientArgs e = new TcpClientArgs(client);
ReadWriteObject readWriteObject = new ReadWriteObject(client);
rws.Add(readWriteObject);
string[] strs=client.Client.RemoteEndPoint.ToString().Split(':');
ips.RemoveAll(c => c.TargetIP == strs[]);
ips.Add(new TCPIP(strs[], strs[], DateTime.Now));
//触发客户端连接成功事件
SuccessConnect(e);
readWriteObject.netStream.BeginRead(readWriteObject.readBytes, , readWriteObject.readBytes.Length, ReadCallback, readWriteObject);
}
catch (Exception ex)
{
throw ex;
}
}
}
private void ReadCallback(IAsyncResult ar)
{
try
{
ReadWriteObject readWriteObject = (ReadWriteObject)ar.AsyncState;
readClient=readWriteObject.client;
if (readClient.Client.Poll(, SelectMode.SelectRead) && (readClient.Client.Available == ) | readClient.Client.Connected)
{
throw new Exception(readWriteObject.client.Client.RemoteEndPoint + "【断开】");
}
int length = readWriteObject.netStream.EndRead(ar);
if (length == ) return;
List<byte> _byteData = new List<byte>();
for (int i = ; i < length; i++)
{
_byteData.Add(readWriteObject.readBytes[i]);
}
ReadCallBackMsg(new BackByteArgs(_byteData.ToArray()));
if (isExit == false)
{
readWriteObject.InitReadArray();
readWriteObject.netStream.BeginRead(readWriteObject.readBytes, , readWriteObject.readBytes.Length, ReadCallback, readWriteObject);
}
}
catch (Exception ex)
{
ReadErrorCallBackMsg(new BackMsgArgs(ex.Message));
}
}
public void SendString(string remoteEndPoint, string str)
{
try
{
ReadWriteObject readWriteObject = rws.Where(c => c.client.Client.RemoteEndPoint.ToString() == remoteEndPoint).FirstOrDefault();
if (readWriteObject.client.Client.Poll(, SelectMode.SelectRead) && (readWriteObject.client.Client.Available == ) || !readWriteObject.client.Client.Connected)
{
throw new Exception(remoteEndPoint + "【断开】");
}
if (readWriteObject != null)
{
readWriteObject.write = MyHelper.HexToByte(str);
readWriteObject.netStream.BeginWrite(readWriteObject.write, , readWriteObject.write.Length, new AsyncCallback(SendCallBack), readWriteObject);
readWriteObject.netStream.Flush(); }
}
catch (Exception ex)
{
throw ex;
}
}
private void SendCallBack(IAsyncResult ar)
{
ReadWriteObject readWriteObject = (ReadWriteObject)ar.AsyncState;
try
{
readWriteObject.netStream.EndWrite(ar);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 停止服务
/// </summary>
public void StopServer()
{
isExit = true;
allDone.Set();
if (listener != null)
listener.Stop();
}
}
}
TCPServer类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading; namespace HY_RFID
{
public class MyTcpClient
{
#region 创建事件
public class RecMsgArgs : EventArgs
{
public readonly string recMsg;
public RecMsgArgs(string recMsg)
{
this.recMsg = recMsg;
}
}
public class RecErrArgs : EventArgs
{
public readonly string recErr;
public RecErrArgs(string recErr)
{
this.recErr = recErr;
}
}
public delegate void ReceivedMsgEventHandler(object sender, RecMsgArgs e);
public event ReceivedMsgEventHandler OnReceived;
protected virtual void ReceivedMsg(RecMsgArgs e)
{
if (OnReceived != null)// 如果有对象注册
{
OnReceived(this, e);// 调用所有注册对象的方法
}
}
public delegate void ReceivedErrorEventHandler(object sender, RecErrArgs e);
public event ReceivedErrorEventHandler OnReceivedErr;
protected virtual void ReceivedError(RecErrArgs e)
{
if (OnReceivedErr != null)// 如果有对象注册
{
OnReceivedErr(this, e);// 调用所有注册对象的方法
}
}
#endregion
private bool isExit;
private Socket socketClient = null;
//连接服务端方法
public void ClientConnect(string IP, string Port)
{
isExit = false;
//定义一个套字节监听 包含3个参数(IP4寻址协议,流式连接,TCP协议)
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//需要获取文本框中的IP地址
IPAddress ipaddress = IPAddress.Parse(IP);
//将获取的ip地址和端口号绑定到网络节点endpoint上
IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(Port));
//这里客户端套接字连接到网络节点(服务端)用的方法是Connect 而不是Bind
socketClient.Connect(endpoint);
//创建一个线程 用于监听服务端发来的消息
Thread threadClient = new Thread(RecMsg);
//将窗体线程设置为与后台同步
threadClient.IsBackground = true;
//启动线程
threadClient.Start();
}
// 发送节目全屏byte串信息到服务端的方法
public void ClientSendMsg(string msg)
{
try
{
if (socketClient.Poll(, SelectMode.SelectRead) && (socketClient.Available == ) || !socketClient.Connected)
{
throw new Exception(socketClient.RemoteEndPoint + "已断开!");
}
Byte[] data = System.Text.Encoding.Default.GetBytes(msg);
socketClient.Send(data, data.Length, SocketFlags.None);//发送信息
}
catch(Exception ex)
{
throw ex;
}
}
//接收服务端发来信息的方法
public void RecMsg()
{ while (!isExit) //持续监听服务端发来的消息
{
try
{
bool o = socketClient.Poll(, SelectMode.SelectRead);
if (o) break;
//定义一个1024*200的内存缓冲区 用于临时性存储接收到的信息
byte[] arrRecMsg = new byte[ * ];
//将客户端套接字接收到的数据存入内存缓冲区, 并获取其长度
int length = socketClient.Receive(arrRecMsg);
if (length == ) return;
string recMsg = Encoding.Default.GetString(arrRecMsg, , length);
ReceivedMsg(new RecMsgArgs(recMsg));
}
catch (SocketException ex)
{
ReceivedError(new RecErrArgs(ex.Message));
}
}
}
/// <summary>
/// 断开链接
/// </summary>
public void StopConnect()
{
if (socketClient != null)
{
socketClient.Close();
isExit = true;
}
}
}
}
TCPClient类
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets; namespace HY_RFID
{
public class ReadWriteObject
{
public TcpClient client;
public NetworkStream netStream;
public byte[] readBytes;
public byte[] write;
public ReadWriteObject(TcpClient client)
{
this.client = client;
netStream = client.GetStream();
readBytes = new byte[client.ReceiveBufferSize];
write=new byte[client.SendBufferSize];
}
public void InitReadArray()
{
readBytes = new byte[client.ReceiveBufferSize];
}
public void InitWriteArray()
{
write=new byte[client.SendBufferSize];
}
}
}
ReadWriteObject类
TCPIP通信的更多相关文章
- 嵌入式Linux软件工程师面试题一
题一,同步和异步有啥区别? 题二,TCP与UDP有啥区别? 题三,进程和线程有啥区别? 题一答案: 同步(Sync):所有的操作都做完,才返回给用户.这样用户在线等待的时间太长,给用户一种卡死了的感觉 ...
- DB2 9.5 数据库分区管理及应用实践
DB2 数据库分区是 DB2 企业版 DPF(Data Partitioning Feature)选件提供的,它主要用来为大规模数据处理.高并发数据访问提供支持.DB2 数据库分区采用 Share-n ...
- 图解TCP-IP协议
本文通过图来梳理TCP-IP协议相关知识.TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道.如图1所示,给出了TCP通信过程的示意图. 图1 TCP 三次握手四次挥手 图1 ...
- TCPIP、Http、Socket的协议~ 写得挺形象,赞
这篇文章写得挺形象,对TCPIP.HTTP.Socket的作用有一个整体层次的理解. 转载文章内容如下: 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 通过初步的了 ...
- [TCPIP] 传输控制协议 Note
TCPIP TCP 传输控制协议 TCP提供一种面向连接的,可靠的字节流服务. 面向连接意味着两个使用TCP的应用在传输数据之前先建立一个TCP连接,这个过程跟打电话相似.在一个TCP连接中仅有两方 ...
- Ⅰ.net通信指前提
①大概搜索了一下,一般提到了这三种居多: Webservice:基于B/S的,可以对外发布方法 Socket:一种网络数据交换模型,Socket接口是TCP/IP网络的API,有三个主要因素:地址.端 ...
- 拿搬东西来解释udp tcpip bio nio aio aio异步
[群主]雷欧纳德简单理解 tcpip是有通信确认的面对面通信 有打招呼的过程 有建立通道的过程 有保持通道的确认 有具体传输udp是看到对面的人好像在对面等你 就往对面扔东西[群主]雷欧 ...
- Linux之TCPIP内核参数优化
/proc/sys/net目录 所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失),例如下面这 ...
- (读书笔记)第2章 TCP-IP的工作方式
第2章 TCP-IP的工作方式 TCP/IP协议系统 为了实现TCP的功能,TCP/IP的创建者使用了模块化的设计.TCP/IP协议系统被分为不同的组件,每个组件分别负责通信过程的一个步骤.这种模块化 ...
随机推荐
- RGB Bayer Color分析
RGB Bayer Color分析 Bayer色彩滤波阵列 拜耳色彩滤波阵列(Bayer Color Filter Array,CFA)是非常有名的彩色图片的数字采集格式.色彩滤波器的模式如上图所示, ...
- ubuntu如何跑arm程序
1. 首先确定一间配置好arm linux 交叉编译器,可以使用arm-linux-gcc. 2. 看示例代码hello.c #include<stdio.h> int add(int a ...
- Using Live555 to Stream Live Video from an IP camera connected to an H264 encoder
http://stackoverflow.com/questions/27279161/using-live555-to-stream-live-video-from-an-ip-camera-con ...
- hdoj 1166 敌兵布阵【线段树求区间最大值+单点更新】
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdoj 1035 Robot Motion
Robot Motion Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- Idea实现WebService实例 转
作者:http://blog.csdn.net/dreamfly88/article/details/52350370 因为工作需要,数据传输部分需要使用webservice实现,经过两天的研究,实现 ...
- phpstudy配置虚拟主机
配置 phpstudy 虚拟主机 1在httpd.conf中 把#Include conf/extra/httpd-vhosts.conf前面的#去掉 2在站点域名管理 添加 要配置的 虚拟主机 添 ...
- NIO机制总结
Selector selector = Selector.open(); 普通的IO流的读取,写入都是一个字节一个字节或一个字符一个字符的循环进行,在这个过程中,程序是阻塞的,inputStream虽 ...
- mysql 配置参数
mysql JDBC Driver 常用的有两个,一个是gjt(Giant Java Tree)组织提供的mysql驱动,其JDBC Driver名称(JAVA类名)为:org.gjt.mm.mysq ...
- 利用图片延迟加载来优化页面性能(jQuery)
图片延迟加载也称懒加载,常用于页面很长,图片很多的页面,以电子商务网站居多,比如大家常上的京东,淘宝,页面以图居多,整个页面少说几百K,多则上兆,如果想一次性加载完成,不仅用户要哭了,服务器也得哭了. ...