最近在开发TCPIP通信,封装了3个类,望各位大神指点指点。
 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通信的更多相关文章

  1. 嵌入式Linux软件工程师面试题一

    题一,同步和异步有啥区别? 题二,TCP与UDP有啥区别? 题三,进程和线程有啥区别? 题一答案: 同步(Sync):所有的操作都做完,才返回给用户.这样用户在线等待的时间太长,给用户一种卡死了的感觉 ...

  2. DB2 9.5 数据库分区管理及应用实践

    DB2 数据库分区是 DB2 企业版 DPF(Data Partitioning Feature)选件提供的,它主要用来为大规模数据处理.高并发数据访问提供支持.DB2 数据库分区采用 Share-n ...

  3. 图解TCP-IP协议

    本文通过图来梳理TCP-IP协议相关知识.TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道.如图1所示,给出了TCP通信过程的示意图. 图1 TCP 三次握手四次挥手 图1 ...

  4. TCPIP、Http、Socket的协议~ 写得挺形象,赞

    这篇文章写得挺形象,对TCPIP.HTTP.Socket的作用有一个整体层次的理解. 转载文章内容如下: 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.   通过初步的了 ...

  5. [TCPIP] 传输控制协议 Note

    TCPIP  TCP 传输控制协议 TCP提供一种面向连接的,可靠的字节流服务. 面向连接意味着两个使用TCP的应用在传输数据之前先建立一个TCP连接,这个过程跟打电话相似.在一个TCP连接中仅有两方 ...

  6. Ⅰ.net通信指前提

    ①大概搜索了一下,一般提到了这三种居多: Webservice:基于B/S的,可以对外发布方法 Socket:一种网络数据交换模型,Socket接口是TCP/IP网络的API,有三个主要因素:地址.端 ...

  7. 拿搬东西来解释udp tcpip bio nio aio aio异步

     [群主]雷欧纳德简单理解 tcpip是有通信确认的面对面通信   有打招呼的过程  有建立通道的过程 有保持通道的确认    有具体传输udp是看到对面的人好像在对面等你 就往对面扔东西[群主]雷欧 ...

  8. Linux之TCPIP内核参数优化

    /proc/sys/net目录 所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失),例如下面这 ...

  9. (读书笔记)第2章 TCP-IP的工作方式

    第2章 TCP-IP的工作方式 TCP/IP协议系统 为了实现TCP的功能,TCP/IP的创建者使用了模块化的设计.TCP/IP协议系统被分为不同的组件,每个组件分别负责通信过程的一个步骤.这种模块化 ...

随机推荐

  1. 命令 "sudo -H" 中的这个 "H" 什么作用?

    脚本中使用$HOME变量 问题描述:某些同事原来写的脚本中包含如下内容. BIN_DIR=${HOME}/tools TAIR_BIN_DIR=${HOME}/tair_bin TAIR_SRC_DI ...

  2. zookeeper与activemq最新存储replicatedLevelDB整合

    测试环境:三台VM虚拟机centos6.4 64位 mini版,IP分别为192.168.1.191/192/193. 测试目的:测试activemq的failover以及与zookeeper的整合 ...

  3. 用CS-Script把Notepad++变身支持智能提示和运行代码的C#集成开发环境

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:用CS-Script把Notepad++变身支持智能提示和运行代码的C#集成开发环境.

  4. 闪回还原点(Flashback Restore Point)

    Flashback Restore Point(闪回还原点) 闪回还原点分两种,一种是Normal Restore Points(正常还原点),另一种是Guaranteed Restore Point ...

  5. easyui 很好很强大

    easyui 很好很强大 http://api.btboys.com/easyui/   中文API教程 分页,拖动等效果很漂亮...

  6. DTrace to Troubleshoot Java Native Memory Problems

    How to Use DTrace to Troubleshoot Java Native Memory Problems on Oracle Solaris 11 Hands-On Labs of ...

  7. Show Global Status 整理

    原文来源:MySQL 5.5 Reference Manual 部分翻译取自:<MySQL_5.1中文参考手册> 转载请注明原文链接http://www.cnblogs.com/lenag ...

  8. apache kafka源码分析-Producer分析---转载

    原文地址:http://www.aboutyun.com/thread-9938-1-1.html 问题导读1.Kafka提供了Producer类作为java producer的api,此类有几种发送 ...

  9. 阿里云SQL Server 2008 客户端导入数据库教程

    一.适用场景   源端数据库是SQL Server 2005 及以上.(SQL Server 2000未测试.) 数据文件总大小在10G以内. 可以在低峰期停应用.   二.导出步骤   1.软件准备 ...

  10. LAMP环境部署总结

    linux+apche+mysql+php 此次用到的工具有:/etc/init.d/iptables , selinux, useradd, yum,chkconfig,sshd,visudo,cr ...