使用c# tcp连续发送短数据时发生连包

wotang2242 2016-09-19 09:02:26
使用c#编写的tcp同步通讯,服务端需要连续发送80条短数据给客户端,但是捕捉端口时发现发送的数据并不是:
数据1
数据2
数据3
而是:数据1数据2数据3这样连在一起的。一般可以通过客户端接收时处理,但是现在客户端是个黑箱,无法改变,想请问下大家要如何让服务端发送时是一条一条发的?通过加延时吗?
...全文
480 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
wotang2242 2016-09-20
  • 打赏
  • 举报
回复
引用 11 楼 owlgame 的回复:
TCP协议本身就不支持设置不粘包,要么改接收端代码拆包,要么改接收端代码告诉发送端已接收数据,要么发送端两次发送间隔够长,要么每发一次建一个连接 如果每发一次建一个连接不适用于你这个情况,那就只能让两次发送间隔时间足够长才行了
谢谢
  • 打赏
  • 举报
回复
引用 6 楼 owlgame 的回复:
对性能要求不高的话,可以每发送一次建一次连接,笨办法
这并不是“笨办法”。短连接和长连接是两种常见的通讯方式,数据的解析和业务处理方式也完全不同。 另外即使是短连接,一段发送数据 123456 另一端也完全可能收到 12345 6 两部分。所以这里的关键是 lz 的 tcp 通讯概念完全不对。
  • 打赏
  • 举报
回复
引用 5 楼 wotang2242 的回复:
[quote=引用 4 楼 sp1234 的回复:] 接收端开发时有bug、连粘包都不知道?你确定是对方的bug?
我并没有说接收端有问题,我也没法知道接收端是如何处理这些数据的。我只是在想发送端有没有办法确认接收端把networkstream的数据拿去了,然后在发送下一条数据,这样能在发送端解决粘包。[/quote] 你发送 123456 123456 123456 数据,接收端本来就是可以得到 12345 61234561 23456 的。既然你们在协议上没有任何规范,那么只能用最外行的做法——无限增加延时——去凑合着对付一下外行的使用者。但是原本用0.5秒钟应该接收完毕的数据,你用1分钟还不能保证程序放到干扰或者网速进一步变化的网络上能够准确接收数据,这种程序难道不应该扔掉吗?
john_QQ:2335298917 2016-09-19
  • 打赏
  • 举报
回复
引用 6 楼 owlgame 的回复:
对性能要求不高的话,可以每发送一次建一次连接,笨办法 List<string> datas = new List<string>(); datas.Add("abc"); datas.Add("123"); datas.Add("456"); datas.Add("zzz"); datas.Add("over"); foreach (string data in datas) { IPAddress ip = IPAddress.Parse("127.0.0.1"); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(ip, int.Parse("8989"))); socket.Send(Encoding.Default.GetBytes(data)); socket.Close(); } Console.WriteLine("send finish!"); Console.ReadKey();
如果接收端无法改变,也就只能用这样的方法了
  • 打赏
  • 举报
回复
对性能要求不高的话,可以每发送一次建一次连接,笨办法 List<string> datas = new List<string>(); datas.Add("abc"); datas.Add("123"); datas.Add("456"); datas.Add("zzz"); datas.Add("over"); foreach (string data in datas) { IPAddress ip = IPAddress.Parse("127.0.0.1"); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(ip, int.Parse("8989"))); socket.Send(Encoding.Default.GetBytes(data)); socket.Close(); } Console.WriteLine("send finish!"); Console.ReadKey();
wotang2242 2016-09-19
  • 打赏
  • 举报
回复
引用 4 楼 sp1234 的回复:
接收端开发时有bug、连粘包都不知道?你确定是对方的bug?
我并没有说接收端有问题,我也没法知道接收端是如何处理这些数据的。我只是在想发送端有没有办法确认接收端把networkstream的数据拿去了,然后在发送下一条数据,这样能在发送端解决粘包。
  • 打赏
  • 举报
回复
接收端开发时有bug、连粘包都不知道?你确定是对方的bug?
wotang2242 2016-09-19
  • 打赏
  • 举报
回复
引用 2 楼 u012948520 的回复:
解黏包啊。。。 写一个结束标志,比如127 127 127 127四联,则认为是一个包结束了 接受一个byte[] b1,还要有一个存放不完整包的byte[] b2 接到一串byte[],先判断是否有结束标志,有则取b2再加上b1结束标志之前的内容为一个完整包,然后把结束标志之后的内容放到b2 如果没有结束标志,则把本次接收内容放到b2的末尾
解黏包我是了解的,但是现在我无法改变接收端,他是封闭的,所以要考虑如何在发送端解决问题。
白衣如花 2016-09-19
  • 打赏
  • 举报
回复
解黏包啊。。。 写一个结束标志,比如127 127 127 127四联,则认为是一个包结束了 接受一个byte[] b1,还要有一个存放不完整包的byte[] b2 接到一串byte[],先判断是否有结束标志,有则取b2再加上b1结束标志之前的内容为一个完整包,然后把结束标志之后的内容放到b2 如果没有结束标志,则把本次接收内容放到b2的末尾
  • 打赏
  • 举报
回复
发送一包数据后,等服务端返回确认已经收到上一包数据再继续发下一包数据。
  • 打赏
  • 举报
回复
TCP协议本身就不支持设置不粘包,要么改接收端代码拆包,要么改接收端代码告诉发送端已接收数据,要么发送端两次发送间隔够长,要么每发一次建一个连接 如果每发一次建一个连接不适用于你这个情况,那就只能让两次发送间隔时间足够长才行了
wotang2242 2016-09-19
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
[quote=引用 6 楼 owlgame 的回复:] 对性能要求不高的话,可以每发送一次建一次连接,笨办法
这并不是“笨办法”。短连接和长连接是两种常见的通讯方式,数据的解析和业务处理方式也完全不同。 另外即使是短连接,一段发送数据 123456 另一端也完全可能收到 12345 6 两部分。所以这里的关键是 lz 的 tcp 通讯概念完全不对。[/quote] 和概念有毛关系?发送的命令即使是一条条分开发的,但是发送到了并不代表接收端取走了,所以他取的时候还是可能会分开或者多条。我想做的就是一条条发,所以想问下大神,tcp中是否有这样的反馈标志,表示接受端已经成功取走了一条数据,然后我再接着发。无法改变接收端的情况下探讨一下方法而已。

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧