【.NET类库】通过SharpSocket进行TCP/UDP通信数据传输
类库作用:
用于基于TCP/UDP协议的数据通信,调用简单,高效。 封装了和业务无关的底层细节,让开发人员可以专注于做业务
完善的示例代码:
针对类库的几种用法,都提供了较为详细的示例代码
一、TCP收发二进制数据:
(服务端)
通过SocketFactory工厂对象,得到一个BinaryTcpServer实例,参数为 监听的端口号。
然后给tcpServerIntance对象绑定事件, 如客户端数量变更、客户端已连接、客户端失连接、收到客户端消息等等
#region 获取ITcpServer的示例 if (tcpServerIntance == null)
{
tcpServerIntance =
SocketFactory.GetBinaryTcpServer(int.Parse(txtPort.Text.Trim()), new BinaryFormattHelper()); //绑定事件
this.tcpServerIntance.ClientCountChanged += new SGDelegate<int>(ClientCountChanged);
this.tcpServerIntance.ClientConnected += new SGDelegate<System.Net.IPEndPoint>(ClientConnected);
this.tcpServerIntance.ClientDisconnected += new SGDelegate<System.Net.IPEndPoint>(ClientDisconnected);
this.tcpServerIntance.MessageReceived += new SGDelegate<IPEndPoint, byte[]>(MessageReceived);
}
#endregion
(客户端)
通过SocketFactory工厂对象,创建一个BinaryTcpClient客户端对象,参数为服务端的IP,服务端的端口号
然后给clientInstance对象绑定相关的事件方法,如断开连接、重连成功等
//获取tcp客户端接口实例
clientInstance = SocketFactory.GetBinaryTcpClient(this.txtIP.Text, int.Parse(this.txtPort.Text), new BinaryFormattHelper()); //绑定事件
clientInstance.MessageReceived += new SGDelegate<System.Net.IPEndPoint, byte[]>(MessageReceived);
clientInstance.ConnectionDisconnected += new SGDelegate(ConnectionInterrupted);
clientInstance.ConnectionReconnectSucceed += new SGDelegate(ConnectionRebuildSucceed); //启动掉线自动重连
clientInstance.AutoReconnect = true; //开始初始化,SharpSocket将初始化和服务端的连接
clientInstance.Initialize();
为了方便演示效果,服务端和客户端分别都做成了WinForm窗体应用程序,这样看起来更直观:
启动服务端,启动之后服务端会监听本机9000端口。
然后启动一个客户端,IP默认本机IP,端口号为服务端的监听端口9000,点击“连接”按钮,提示连接成功
此时看一下服务端的界面,会发现服务端监测到了客户端的连接。
数据传输:
我们在客户端选择两个数字,然后选择一个运算符号,把这些信息发送给服务端,我们期望服务端接受这些信息,执行相应的计算,并返回计算结果给客户端
点击提交
可以看到运算的结果已经从服务端获取
数据是如何从客户端传给服务端?服务端又是如何返回结果给客户端呢?
(客户端发送数据给服务端)
//请求消息体
RequestFormat contract = new RequestFormat(int.Parse(this.textBox1.Text), int.Parse(this.textBox2.Text));
byte[] bBody = SerializeHelper.SerializeObject(contract); //消息头
MessageHead head = new MessageHead(bBody.Length, msgType);
byte[] bHead = head.ToStream(); //构建请求消息
byte[] reqMessage = new byte[bHead.Length + bBody.Length];
Buffer.BlockCopy(bHead, , reqMessage, , bHead.Length);
Buffer.BlockCopy(bBody, , reqMessage, bHead.Length, bBody.Length); //发送请求消息
clientInstance.PostDataToServer(reqMessage);
(服务端返回数据给客户端)
//回复消息体
ResponseFormat response = new ResponseFormat(request.Number1, request.Number2, operationType, result);
byte[] bReponse = SerializeHelper.SerializeObject(response); //回复消息头
MessageHead head = new MessageHead(bReponse.Length, MessageType.Result);
byte[] bHead = head.ToStream(); //构建回复消息
byte[] resMessage = new byte[bHead.Length + bReponse.Length];
Buffer.BlockCopy(bHead, , resMessage, , bHead.Length);
Buffer.BlockCopy(bReponse, , resMessage, bHead.Length, bReponse.Length); //发送回复消息
tcpServerIntance.PostDataToClient(client, resMessage);
可以看到,都是通过byte[]的形式进行数据传递的,用于传递的byte[]代表一个消息,消息包含消息头和消息体,消息头是固定长度的,具体长度要根据服务端和客户端直接商定的协议来确定
在实例代码中,消息头的长度HeadLength为8位
二、TCP收发文本数据
服务端:
创建TextTcpServer对象,绑定事件,然后启动监听
#region 获取ITcpServer的示例 if (tcpServerIntance == null)
{
//DefaultTextFormatHelper是自带的使用UTF8编码,兼容中英文
tcpServerIntance =
SocketFactory.GetTextTcpServer(int.Parse(txtPort.Text.Trim()), new DefaultTextFormatHelper("\0")); //绑定事件
this.tcpServerIntance.ClientCountChanged += new SGDelegate<int>(ClientCountChanged);
this.tcpServerIntance.ClientConnected += new SGDelegate<System.Net.IPEndPoint>(ClientConnected);
this.tcpServerIntance.ClientDisconnected += new SGDelegate<System.Net.IPEndPoint>(ClientDisconnected);
this.tcpServerIntance.MessageReceived += new SGDelegate<IPEndPoint, byte[]>(MessageReceived);
}
#endregion #region 启动监听
tcpServerIntance.Initialize();
#endregion
客户端:
创建TextTcpClient对象,绑定事件,执行Initialize()初始化方法
//初始化并启动客户端引擎(TCP、文本协议)
clientInstance = SocketFactory.GetTextTcpClient(this.txtIP.Text, int.Parse(this.txtPort.Text), new DefaultTextFormatHelper("\0"));
clientInstance.MessageReceived += new SGDelegate<System.Net.IPEndPoint, byte[]>(MessageReceived);
clientInstance.AutoReconnect = true;//启动掉线自动重连
clientInstance.ConnectionDisconnected += new SGDelegate(ConnectionDisconnected);
clientInstance.ConnectionReconnectSucceed += new SGDelegate(ConnectionRebuildSucceed);
clientInstance.Initialize();
演示效果:
启动服务端并监听端口
启动客户端并连接端口
连接成功之后,服务端会有上线提示,并且会自动记录上线客户端数量
客户端尝试一下向服务端发送数据,服务端接收到了客户端发送的数据,并展示
尝试一下服务端向客户端发送数据,试试发送json字符串。
客户端收到了服务端发送的json字符串
那么客户端具体是如何把数据发送给服务端?服务端又是如何进行回复的呢?
客户端发送数据
//将待发送的原始字符串加上 "\0"字符,代表一帧的结尾,方便服务端根据这个来过滤
string msg = this.txtMsg.Text + "\0"; //使用UTF-8编码数据
byte[] bMsg = System.Text.Encoding.UTF8.GetBytes(msg); //发走
clientInstance.SendDataToServer(bMsg);
服务端接受数据
//使用UTF-8编码
string msg = System.Text.Encoding.UTF8.GetString(bMsg);
//将结束标记"\0"去掉,得到的就是原始字符串
msg = msg.Substring(, msg.Length - );
服务端回复数据
//原始要发送的字符串加上一个结尾字符,由于使用的是DefaultTextFormatHelper,因此这里用"\0" 表示一个消息的结尾
string msg = this.textBox_msg.Text + "\0"; //DefaultTextFormatHelper使用UTF-8编码
byte[] bMsg = System.Text.Encoding.UTF8.GetBytes(msg); tcpServerIntance.SendDataToClient(client, bMsg);
可以看到,在进行字符串、json或者xml等一些非结构化的数据传输时,也是先将内容转化成字节数组。
与TCP的二进制数据传输不同的时,这里不区分消息头和消息体,只是由客户端和服务端预定义了帧的结束符,在每一帧消息的末尾加上这个结束符,方便服务端和客户端进行解析
三、UDP收发任意数据
基于UDP协议的数据通讯,不需要客户端提前建立连接
(服务端)
服务端通过SocketFactory.GetUdp()方法,创建UDP通信实例,并设定本端使用的端口号,注册消息事件并初始化
//创建一个接口实例,然后就可以操作它了
udpServerInstance = SocketFactory.GetUdp(); //设置本端使用的端口号
udpServerInstance.Port = int.Parse(this.edtPort.Text); //订阅本接口的收到数据的事件通知,当收到数据后,自动回调您注册的方法
udpServerInstance.MessageReceived += new SGDelegate<IPEndPoint, byte[]>(MessageReceived); //启动即可
udpServerInstance.Initialize();
(客户端)
根据IP和端口号创建服务端终结点,通过SocketFactory.GetUdp()创建UDP实例
//得到服务端终结点
serverEndPoint = new IPEndPoint(IPAddress.Parse(this.edtIP.Text), int.Parse(this.edtPort.Text)); if (this.udpClientInstance == null)
{
//初始化并启动客户端引擎(UDP)
udpClientInstance = SocketFactory.GetUdp(); //订阅接收到数据的事件
udpClientInstance.MessageReceived += new SGDelegate<System.Net.IPEndPoint, byte[]>(MessageReceived); //启动UDP连接
udpClientInstance.Initialize();
客户端根据用户请求,构建消息头和消息体,并调用udpClientInstance.SendData(serverEndPoint,reqMessage);方法向服务端发送数据
int msgType = this.cmdOpType.SelectedIndex == ? MessageType.Add : MessageType.Multiple; //请求消息体
RequestFormat contract = new RequestFormat(int.Parse(this.edtFirst.Text), int.Parse(this.edtSecond.Text));
byte[] bBody = SerializeHelper.SerializeObject(contract); //消息头
MessageHead head = new MessageHead(bBody.Length, msgType);
byte[] bHead = head.ToStream(); //构建请求消息
byte[] reqMessage = new byte[bHead.Length + bBody.Length];
Buffer.BlockCopy(bHead, , reqMessage, , bHead.Length);
Buffer.BlockCopy(bBody, , reqMessage, bHead.Length, bBody.Length); //发送请求消息
udpClientInstance.SendData(serverEndPoint, reqMessage);
服务端收到数据之后,解析收到的信息,执行相应的运算操作,并把结果返回给客户端
#region 解析消息体
RequestFormat request = (RequestFormat)SerializeHelper.DeserializeBytes(bMsg, MessageHead.HeadLength, bMsg.Length - MessageHead.HeadLength);
int result = ;
string operationType = "";
if (msgType == MessageType.Add)
{
result = request.Number1 + request.Number2;
operationType = "加法";
}
else if (msgType == MessageType.Multiple)
{
result = request.Number1 * request.Number2;
operationType = "乘法";
}
else
{
operationType = "错误的操作类型";
}
#endregion #region 显示请求
string msg = string.Format("请求类型:{0},操作数1:{1},操作数2:{2}", operationType, request.Number1 , request.Number2);
ShowStr(client, msg);
#endregion #region 回复消息体
ResponseFormat response = new ResponseFormat(request.Number1, request.Number2, operationType, result);
byte[] bReponse = SerializeHelper.SerializeObject(response);
#endregion #region 回复消息头
MessageHead head = new MessageHead(bReponse.Length, MessageType.Result);
byte[] bHead = head.ToStream();
#endregion #region 构建回复消息
byte[] resMessage = new byte[bHead.Length + bReponse.Length];
Buffer.BlockCopy(bHead, , resMessage, , bHead.Length);
Buffer.BlockCopy(bReponse, , resMessage, bHead.Length, bReponse.Length);
#endregion #region 发送回复消息
udpServerInstance.SendData(client, resMessage);
#endregion
【.NET类库】通过SharpSocket进行TCP/UDP通信数据传输的更多相关文章
- 高性能 TCP & UDP 通信框架 HP-Socket v3.5.3
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.5.2
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.5.1
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.4.1
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.3.1
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- HP-SOCKET TCP/UDP通信框架库解析
项目概述: HP-SOCKET是一套通用TCP/UDP通信框架,包括服务器.客户端.Agent组件:其目标是提供高性能.通用性.简易性.可扩展.可定制: 鉴于此,其仅实现基本的通用框架通信.数据收发功 ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.2.3
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.2.2 正式发布
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- python实现TCP/UDP通信
一.说明 对于TCP/udp的说明已经很多了,我在这里只是简单的说明一下 二.套接字scoket 套接字是一种具有之前所说的"通信端点"概念的计算网络数据结构.相当于电话插口,没它 ...
随机推荐
- springcloud feign增加熔断器Hystrix
1.依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>s ...
- Kylin-2.6.2集群部署
1. 集群节点规划与说明 rzx1 all rzx2 query rzx3 query 说明: Kylin节点角色有三种: all: 包含query和job query: 查询节点 job: 工作节点 ...
- 经典sql题练习50题
-- 1.查询"01"课程比"02"课程成绩高的学生的信息及课程分数 select a.* ,b.s_score as 01_score,c.s_score a ...
- spring aop的前奏,动态代理 (5)
目录 一.先看一个计算器的抽取和实现 二.使用动态代理解决以上问题. 1 设计原理 2 代码实现 2.1 接口代码 2.2 实现接口的代码 2.3 测试代码 2.3 创建动态代理类 2.4 动态代理类 ...
- CSS:CSS Positioning(定位)
ylbtech-CSS:CSS Positioning(定位) 1.返回顶部 1. CSS Positioning(定位) position 属性指定了元素的定位类型. position 属性的四个值 ...
- Openstack组件部署 — Networking service_Compute Node
目录 目录 前文列表 安装组件 配置通用组件 配置自服务网络选项 配置Linux 桥接代理 配置Nova使用网络 完成安装 验证操作Execute following commands on Cont ...
- 1.4 React 组件生命周期
1.4.1 组件 React 中组件有自己的生命周期方法,简单理解可以为组件从 出生(实例化) -> 激活 -> 销毁 生命周期 hook.通过这些 hook 方法可以自定义组件的特性. ...
- SQL中Truncate语法
转自:http://www.studyofnet.com/news/555.html 本文导读:删除表中的数据的方法有delete,truncate, 其中TRUNCATE TABLE用于删除表中的所 ...
- leetcode 1041——困于环中的机器人
描述: 在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方.机器人可以接受下列三条指令之一: "G":直走 1 个单位 "L":左转 90 度 &quo ...
- Ubuntu 14.04 64位上安装wps office软件
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/tao_627/article/details/24179933 废话少说,仅仅给出方法供各位參考! ...