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协议系统被分为不同的组件,每个组件分别负责通信过程的一个步骤.这种模块化 ...
随机推荐
- jQuery 的属性操作方法
jQuery 属性操作方法 下面列出的这些方法获得或设置元素的 DOM 属性. 这些方法对于 XML 文档和 HTML 文档均是适用的,除了:html(). 方法 描述 addClass() 向匹配的 ...
- Code Forces Gym 100971D Laying Cables(单调栈)
D - Laying Cables Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u ...
- iptables的实战整理
一.iptables使用场景: 内网情况下使用:在大并发的情况下不要开iptables否则影响性能 二.iptables出现下面的问题: 在yewufa ...
- IO(Input Output)流__字节流
续: ------->>>>字节流 IntputStream OutputStream 需求:想要操作图片数据,就需要用到字节流. 读写操作: FileOutputStrea ...
- PHP文件操作常用函数总结
一 .解析路径: 1 获得文件名: basename(); 给出一个包含有指向一个文件的全路径的字符串,本函数返回基本的文件名.如果文件名是以 suffix 结束的,那这一部分也会被去掉. eg: $ ...
- 验证码 jsp生成
<%@ page contentType="image/jpeg" import="java.awt.*, java.awt.image.*,java.util.* ...
- java方法的重载
java方法的重载 public class Person1 { private String name; //姓名 private int age; //年龄 priva ...
- Lamda和Linq语法对比详细
本人转载:http://www.cnblogs.com/knowledgesea/p/3897665.html 闲言碎语 近期比较忙,但还是想写点什么,就分享一些基础的知识给大家看吧,希望能帮助一些l ...
- 读书雷达 l 业务分析师(BA)篇
http://chuansong.me/n/412991951441 ThoughtWorks BA社区从2011年起就建立了BA书橱,根据大家的推荐选择了来自软件需求.商业分析.设计思维.软技能,以 ...
- Activiti5.16.4数据库表结构
一.ACTIVITI 数据库E-R图(5.16.4) Activiti 5.16.4 总共有24张表,增加act_evt_log(事件日志),以及增加了对SasS的支持. 在流程定义.运行实例和历史的 ...