C#Socket.Send():它是否发送所有数据?

C#Socket.Send():它是否发送所有数据?,c#,.net,sockets,tcp,C#,.net,Sockets,Tcp,我在读Richard Blum的《C#Network Programming》一书中有关套接字的内容。下面的摘录说明Send()方法不能保证发送传递给它的所有数据 基于此代码,您可能会认为 整个1024字节的数据缓冲区已发送到远程设备。。。但是这个 这可能是个错误的假设。取决于内部TCP的大小 缓冲区和正在传输的数据量,可能不是 提供给Send()方法的所有数据实际上都已发送 然而,当我去查看Microsoft文档时,它说: 如果您使用的是面向连接的协议,Send将一直阻止,直到 除非设置了超时

我在读Richard Blum的《C#Network Programming》一书中有关套接字的内容。下面的摘录说明Send()方法不能保证发送传递给它的所有数据

基于此代码,您可能会认为 整个1024字节的数据缓冲区已发送到远程设备。。。但是这个 这可能是个错误的假设。取决于内部TCP的大小 缓冲区和正在传输的数据量,可能不是 提供给Send()方法的所有数据实际上都已发送

然而,当我去查看Microsoft文档时,它说:

如果您使用的是面向连接的协议,Send将一直阻止,直到 除非设置了超时,否则将发送缓冲区中的所有字节

那是哪一个呢?这本书是2004年出版的,从那以后它有没有改变


我计划使用异步套接字,所以我的下一个问题是,BeginSend()会发送所有数据吗?

您引用的两个资源都是正确的。不过,我认为措辞本可以更好。 文件中也写着

也不能保证您发送的数据会显示在 立即建立网络。为了提高网络效率,底层 系统可能会延迟传输,直到有大量传出数据 收集数据

所以,
Send
方法是阻塞的,直到底层系统有空间为网络发送缓冲您的数据

Send方法的成功完成意味着基础 系统有空间为网络发送缓冲您的数据


你所要做的就是阅读你引用的同一段落的其余部分。你在同一句话中的引用甚至有例外

如果您使用的是面向连接的协议,则除非使用Socket.SendTimeout设置了超时,否则Send将一直阻止,直到发送缓冲区中的所有字节。如果超过超时值,发送调用将抛出SocketException在非阻塞模式下,即使发送少于缓冲区中的字节数,发送也可能成功完成。应用程序负责跟踪发送的字节数,并重试该操作,直到应用程序将字节发送到缓冲区。

对于
BeginSend
,还描述了该行为:

回调方法应该调用EndSend方法。当应用程序调用BeginSend时,系统将使用单独的线程执行指定的回调方法,将在EndSend上阻塞,直到套接字发送请求的字节数或引发异常为止


这不是一个很好的设计,并且破坏了回调的全部意义!考虑使用替代(然后你仍然需要检查<代码> ByTeTrSangsDebug < /Cord>属性)。

你在Doc中没有看到“-”MICKY:忽略有利于黑盒观察的文档是一个非常糟糕的想法,这导致在其他计算机上,在Windows更新之后,代码失败。甚至当你的计算机碰巧有更多或更少的线程准备同时运行时。@BenVoigt也许。但是,同样地,文档形成了一个契约,如果行为依赖于环境,那么文档应该说so@MickyD:事实上,这些文件构成了一份合同。所有环境都必须遵守该合同。有些环境可能会做得更多,但不需要文档来详细说明合同以外的任何内容。@BenVoigt ok,谢谢你
byte[] data = new byte[1024];
int sent = socket.Send(data);