如何在socket+tcp中添加数据包并解包

1个回答
展开全部
摘要 对不起,TCP Socket 接收数据包的时候是无法控制每次接收数据包的个数的. 发送方可以一个一个地发,到了接收方根本不能保证一个一个地收,大部分时间可能是只收到一个,但有时候可能收到多个甚至部分数据包.
对这种情况通常是靠接收方利用包头做解析,这个工作可以占到一个Socket程序的一大部分代码.
最常用的手法是把接受到的Byte[]加到一个缓存里,比如List ,每次处理的时候根据包头的定义按照包的长度从List从第一个byte开始取出只一个完整的包来处理,剩下的数据属于第二或者第三个包的. 如果List 的数据长度不够一个包的,就暂时不处理,等到后续的数据都收到了再按照一个完整的包处理.
我上次给你的那个例子里就有处理包的代码,你可以参考下.
咨询记录 · 回答于2022-04-08
如何在socket+tcp中添加数据包并解包
对不起,TCP Socket 接收数据包的时候是无法控制每次接收数据包的个数的. 发送方可以一个一个地发,到了接收方根本不能保证一个一个地收,大部分时间可能是只收到一个,但有时候可能收到多个甚至部分数据包. 对这种情况通常是靠接收方利用包头做解析,这个工作可以占到一个Socket程序的一大部分代码. 最常用的手法是把接受到的Byte[]加到一个缓存里,比如List ,每次处理的时候根据包头的定义按照包的长度从List从第一个byte开始取出只一个完整的包来处理,剩下的数据属于第二或者第三个包的. 如果List 的数据长度不够一个包的,就暂时不处理,等到后续的数据都收到了再按照一个完整的包处理. 我上次给你的那个例子里就有处理包的代码,你可以参考下.
你要分清楚几种包:你自己定义的包、TCP包、IP包,你自己定义的包太大,TCP/IP会给你拆包,也许你用EtherPeek.NX看到的包是TCP/IP包呢。如果TCP/IP包里面有分拆原始包的记录(我不知道有没有),也许能复原呢,但这也需要你直接处理底层的TCP/IP包。 其实对于不清楚TCP/IP底层的人来说,还是定义统一的包格式比较好。
就先权当是只有一个包 用c的方法去实现服务端与客户端发包解包的过程
最简单的代码如何写
请稍等
好的
private void btnSend_Click(object sender, EventArgs e) { //组合出远程终结点 IPAddress ipAddress = IPAddress.Parse(this.txtIP3.Text); IPEndPoint hostEP = new IPEndPoint(ipAddress, Convert.ToInt32(this.txtPort3.Text)); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { socket.Connect(hostEP); //1.发送用户协议 string path1 = Environment.CurrentDirectory; //获取应用程序的当前工作目录。 string doc = "YourSendFile.pdf"; string path = Path.Combine(path1, doc); FileStream fs = File.Open(path, FileMode.Open); //文件内容 byte[] bdata = new byte[fs.Length]; fs.Read(bdata, 0, bdata.Length); fs.Close(); //文件扩展名,固定3字节 byte[] fileExtArray = Encoding.UTF8.GetBytes(string.Format("{0:D3}", currentDocExt)); //文件长度, 固定为20字节,前面会自动补零 byte[] fileLengthArray = Encoding.UTF8.GetBytes(bdata.Length.ToString("D20")); //合并byte数组 byte[] fileArray = CombomBinaryArray(fileExtArray, fileLengthArray); //合并byte数组 byte[] bdata1 = CombomBinaryArray(fileArray, bdata); //发文件长度+文件内容 socket.Send(bdata1, bdata1.Length, 0); //2.接收 //声明接收返回内容的字符串 string recvStr = ""; //声明字节数组,一次接收数据的长度为 1024 字节 byte[] recvBytes = new byte[1024]; //返回实际接收内容的字节数 int bytes = 0; //循环读取,直到接收完所有数据 while (true) { bytes = socket.Receive(recvBytes, recvBytes.Length, 0); //读取完成后退出循环 if (bytes <= 0) break; //将读取的字节数转换为字符串 recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes); } //禁用 Socket socket.Shutdown(SocketShutdown.Both); //关闭 Socket socket.Close(); //... do some busness logic ... } catch (Exception e1) { throw e1; } }复制代码
下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消