SOCKET 发送数据

six-years 2017-04-24 04:05:36
socket 以TCP的模式发送数据,
一台服务器和多个客户端以1S的频率发送数据,一包16K,
通过打印日志看到服务端send函数确实阻塞了10S,然而客户端却在1S内就完成了接收。也就是说在客户端接受完成后服务端还阻塞了9S,这个情况该怎么破
...全文
599 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
showjim 2017-04-26
  • 打赏
  • 举报
回复
引用 23 楼 wangjun8868 的回复:
你们纠结毛线啊 http://bbs.csdn.net/topics/392158734 好东西帮你解决一切烦恼
粘包 就是 一切烦恼?真的不明白一个只管收发包的框架和直接使用 Socket 能有多大区别。
编程有钱人了 2017-04-26
  • 打赏
  • 举报
回复
你们纠结毛线啊 http://bbs.csdn.net/topics/392158734 好东西帮你解决一切烦恼
six-years 2017-04-25
  • 打赏
  • 举报
回复
引用 14 楼 sp1234 的回复:
[quote=引用 11 楼 Q1092926267 的回复:] 我们一台服务器控制一千多个客户端,当然那个性能好用哪个
目前来看,一个客户端就已经不能保证正确了。[/quote] 很遗憾确实能运行一千多个客户端,而且服务器也就两三万的低端货。 另外对省去解析部分给你带来的误导表示抱歉,不过也没办法通信协议公司保密要求还是蛮严格的,不删掉放到网上这确实不合适。
six-years 2017-04-25
  • 打赏
  • 举报
回复
引用 13 楼 sp1234 的回复:
[quote=引用 8 楼 Q1092926267 的回复:] 1.肯定不是receive导致的阻塞,因为我发送完成后会打印状态的, 2.某些原因我也在查, 3sendto和send效果一样,就连beginsend都会导致阻塞10S,而且从日志上看出endsend在1S内执行完,但是beginsend还是需要阻塞10S,这一点是很不符合逻辑的,无论是通过其他方式做实验还是微软的说明都是说beginsend不会阻塞,只是回调句柄中的endsend才会阻塞到发送完成,这是个很费解的事。 更费解的是客户端都受到了数据,send还在阻塞,这是个无法理解的事。
不是说 receive 导致了阻塞,你贴的代码说明你在 Receive 和 Send 的分离上,根本就是一个诡异的内部理解问题,也就是说你在本质上没有理解如何编写通讯程序、然后把无关的东西放在一起,为了这中纠结,你一定是还另外写了一大堆复杂的东西来调和这些诡异的结果,而那些部分一定阻塞了——但是你自己更加不理解那些部分的 bug。 一个使用同步 Recieve 的小程序(主要是自己练习用的),直接写
 void ControllerTCPComunication(object obj)
        {
            Socket socket = (Socket)obj;
 while(true){
            byte[] data = new byte[16384];
            var len = socket.Receive(data);
            处理解析收到的数据(data, len);
              }
}
这才是正确的模式。那么当解析到确实接收到了一个完整的信息,假设需要返回,在处理解析的部分去随时可以 Send 返回数据;但是假设没有收到完整的数据包,不能解析和执行,就不会 Send 返回值。 而你的程序,只 Receive,不解析,就莫名其妙地不知从哪里找来数据 Send 数据,可以说编程流程完全相反。完全不可理解。除非你说你贴错了代码了,少写了多少调代码,否则这个代码可以证明你们有一大堆诡异的代码在另外做一些事情,才会有这种诡异的流程。[/quote] 解析肯定是有的 解析过程中的校验,分包操作等等都不会少,只是我觉得问一个技术性的问题没有必要把冗长的解析代码贴出来罢了,何况我贴代码的时候也明确了“大概”这个意思。
six-years 2017-04-25
  • 打赏
  • 举报
回复
引用 12 楼 sp1234 的回复:
void ControllerTCPComunication(object obj) { Socket socket = (Socket)obj; socket.SendBufferSize = 65536; while(true){ byte[] data = new byte[16384]; socket.Receive(data); socket.Send(new byte[]{......}) Console.WriteLine("发送成功“); } } 这种代码我是完全“不能理解”啊! 当你发送消息(包括返回值),你直接 send 就行了,跟 Receive 有什么纠结?为什么在接收数据的过程中写 send 语句?为什么 send 之前要写一条 Receive 语句? 如果不懂得左右手分开的道理,那就是还没有理解左右手。你这里的流程实在是完全没有理解收发数据的流程问题。
这个是举个例子,为什么要receive,肯定是有业务需求的,比如说我收到了1号指令必须回复给发送端2号指令,也就是说send不是随随便便的,必须receive以后根据收到的指令进行send。
  • 打赏
  • 举报
回复
引用 11 楼 Q1092926267 的回复:
我们一台服务器控制一千多个客户端,当然那个性能好用哪个
目前来看,一个客户端就已经不能保证正确了。
  • 打赏
  • 举报
回复
引用 8 楼 Q1092926267 的回复:
1.肯定不是receive导致的阻塞,因为我发送完成后会打印状态的, 2.某些原因我也在查, 3sendto和send效果一样,就连beginsend都会导致阻塞10S,而且从日志上看出endsend在1S内执行完,但是beginsend还是需要阻塞10S,这一点是很不符合逻辑的,无论是通过其他方式做实验还是微软的说明都是说beginsend不会阻塞,只是回调句柄中的endsend才会阻塞到发送完成,这是个很费解的事。 更费解的是客户端都受到了数据,send还在阻塞,这是个无法理解的事。
不是说 receive 导致了阻塞,你贴的代码说明你在 Receive 和 Send 的分离上,根本就是一个诡异的内部理解问题,也就是说你在本质上没有理解如何编写通讯程序、然后把无关的东西放在一起,为了这中纠结,你一定是还另外写了一大堆复杂的东西来调和这些诡异的结果,而那些部分一定阻塞了——但是你自己更加不理解那些部分的 bug。 一个使用同步 Recieve 的小程序(主要是自己练习用的),直接写
 void ControllerTCPComunication(object obj)
        {
            Socket socket = (Socket)obj;
 while(true){
            byte[] data = new byte[16384];
            var len = socket.Receive(data);
            处理解析收到的数据(data, len);
              }
}
这才是正确的模式。那么当解析到确实接收到了一个完整的信息,假设需要返回,在处理解析的部分去随时可以 Send 返回数据;但是假设没有收到完整的数据包,不能解析和执行,就不会 Send 返回值。 而你的程序,只 Receive,不解析,就莫名其妙地不知从哪里找来数据 Send 数据,可以说编程流程完全相反。完全不可理解。除非你说你贴错了代码了,少写了多少调代码,否则这个代码可以证明你们有一大堆诡异的代码在另外做一些事情,才会有这种诡异的流程。
  • 打赏
  • 举报
回复
void ControllerTCPComunication(object obj) { Socket socket = (Socket)obj; socket.SendBufferSize = 65536; while(true){ byte[] data = new byte[16384]; socket.Receive(data); socket.Send(new byte[]{......}) Console.WriteLine("发送成功“); } } 这种代码我是完全“不能理解”啊! 当你发送消息(包括返回值),你直接 send 就行了,跟 Receive 有什么纠结?为什么在接收数据的过程中写 send 语句?为什么 send 之前要写一条 Receive 语句? 如果不懂得左右手分开的道理,那就是还没有理解左右手。你这里的流程实在是完全没有理解收发数据的流程问题。
six-years 2017-04-25
  • 打赏
  • 举报
回复
引用 10 楼 Libby1984 的回复:
既然是TCP通讯,为什么不直接用C#封装好了的TCP通讯接口呢,一样是Sockt。服务端使用TcpListener ,客户端使用TcpClient。 http://www.cnblogs.com/jhlong/p/5799248.html
我们一台服务器控制一千多个客户端,当然那个性能好用哪个
  • 打赏
  • 举报
回复
既然是TCP通讯,为什么不直接用C#封装好了的TCP通讯接口呢,一样是Sockt。服务端使用TcpListener ,客户端使用TcpClient。 http://www.cnblogs.com/jhlong/p/5799248.html
six-years 2017-04-25
  • 打赏
  • 举报
回复
引用 7 楼 stherix 的回复:
你用的都是同步发送和接收 socket.Receive(data); 这句话肯定会引起问题啊,先必须收到客户端发来的包才会往下面走的,没收到会等待
不是的,通过日志上可以看出是阻塞在send函数,意思就是说你发送了一包数据,客户端完成接收后服务端send函数仍然会阻塞10S
six-years 2017-04-25
  • 打赏
  • 举报
回复
引用 6 楼 Libby1984 的回复:
1. 你在Send之前还调用了Receive函数,是否是Receive函数阻塞了send函数的调用。你可以暂时将Receive函数注释掉看send是否还是阻塞。 2. 是不是某些其他原因导致发送字节很慢,下面是MSDN中一段关于Send函数的描述,Send在发送完所有字节前是阻塞的 如果您使用的是面向连接的协议,则除非使用 Socket..::.SendTimeout 设置了超时值,否则,Send 将一直处于阻止状态,直到发送完缓冲区中的所有字节。如果超过超时值,Send 调用将引发 SocketException。在非阻止模式下,Send 可能会成功完成,即使它发送的字节数小于缓冲区中的字节数。应由您的应用程序负责跟踪已发送的字节数并重试操作,直到应用程序发送了缓冲区中的字节数为止。不能保证发送的数据会立即出现在网络上。为提高网络效率,基础系统可能会延迟传输,直到收集了足够多的传出数据后才开始发送。Send 方法的成功完成意味着基础系统有空间来缓冲用于网络发送的数据。 3. 试试用SendTo替换Send方法
1.肯定不是receive导致的阻塞,因为我发送完成后会打印状态的, 2.某些原因我也在查, 3sendto和send效果一样,就连beginsend都会导致阻塞10S,而且从日志上看出endsend在1S内执行完,但是beginsend还是需要阻塞10S,这一点是很不符合逻辑的,无论是通过其他方式做实验还是微软的说明都是说beginsend不会阻塞,只是回调句柄中的endsend才会阻塞到发送完成,这是个很费解的事。 更费解的是客户端都受到了数据,send还在阻塞,这是个无法理解的事。
stherix 2017-04-25
  • 打赏
  • 举报
回复
你用的都是同步发送和接收 socket.Receive(data); 这句话肯定会引起问题啊,先必须收到客户端发来的包才会往下面走的,没收到会等待
  • 打赏
  • 举报
回复
1. 你在Send之前还调用了Receive函数,是否是Receive函数阻塞了send函数的调用。你可以暂时将Receive函数注释掉看send是否还是阻塞。 2. 是不是某些其他原因导致发送字节很慢,下面是MSDN中一段关于Send函数的描述,Send在发送完所有字节前是阻塞的 如果您使用的是面向连接的协议,则除非使用 Socket..::.SendTimeout 设置了超时值,否则,Send 将一直处于阻止状态,直到发送完缓冲区中的所有字节。如果超过超时值,Send 调用将引发 SocketException。在非阻止模式下,Send 可能会成功完成,即使它发送的字节数小于缓冲区中的字节数。应由您的应用程序负责跟踪已发送的字节数并重试操作,直到应用程序发送了缓冲区中的字节数为止。不能保证发送的数据会立即出现在网络上。为提高网络效率,基础系统可能会延迟传输,直到收集了足够多的传出数据后才开始发送。Send 方法的成功完成意味着基础系统有空间来缓冲用于网络发送的数据。 3. 试试用SendTo替换Send方法
足球中国 2017-04-25
  • 打赏
  • 举报
回复
你连了多少个客户端??一个??一半的代码让别人猜着玩嘛?
showjim 2017-04-25
  • 打赏
  • 举报
回复
一堆人在说教 Socket 的使用方式,结果很喜剧啊。
SoulRed 2017-04-25
  • 打赏
  • 举报
回复
非常建议你用下微软推荐的SAEA这个IOCP 的socket封装。非常好用。比你单用socket性能要高好多倍,因为他是被动的。我喜欢被动的模式。
six-years 2017-04-25
  • 打赏
  • 举报
回复
谢谢楼上几位的回答,刚发现是打印发送的指令导致耗时过长,跟send没什么关系。
  • 打赏
  • 举报
回复
能用同步就用同步,异步逻辑有点绕,不好查错
six-years 2017-04-24
  • 打赏
  • 举报
回复
引用 2 楼 xdashewan 的回复:
send也有异步方法的
异步发送也是一样的效果,EndSend后,BeginSend还是需要9S才能关闭,
加载更多回复(4)

111,097

社区成员

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

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

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