C# Socket.Send() : does it send all data or not?

标签 c# .net sockets tcp

我正在阅读理查德·布鲁姆(Richard Blum)所著的《C# 网络编程》一书中有关套接字的内容。以下摘录指出,不保证 Send() 方法发送传递给它的所有数据。

byte[] data = new byte[1024];
int sent = socket.Send(data);

On the basis of this code, you might be tempted to presume that the entire 1024-byte data buffer was sent to the remote device... but this might be a bad assumption. Depending on the size of the internal TCP buffer and how much data is being transferred, it is possible that not all the data supplied to the Send() mehtod was actually sent.

但是,当我去查看 Microsoft 文档 https://msdn.microsoft.com/en-us/library/w93yy28a(v=vs.110).aspx 时它说:

If you are using a connection-oriented protocol, Send will block until all of the bytes in the buffer are sent, unless a time-out was set

那么它是哪一个呢?这本书是2004年出版的,那么从那时起它有变化吗?

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

最佳答案

您所要做的就是阅读您引用的同一段落的其余部分。在同一句话中甚至有一个异常(exception)。

If you are using a connection-oriented protocol, Send will block until all of the bytes in the buffer are sent, unless a time-out was set by using Socket.SendTimeout. If the time-out value was exceeded, the Send call will throw a SocketException. In nonblocking mode, Send may complete successfully even if it sends less than the number of bytes in the buffer. It is your application's responsibility to keep track of the number of bytes sent and to retry the operation until the application sends the bytes in the buffer.

对于BeginSend,还描述了行为:

Your callback method should invoke the EndSend method. When your application calls BeginSend, the system will use a separate thread to execute the specified callback method, and will block on EndSend until the Socket sends the number of bytes requested or throws an exception.

这不是一个很好的设计,并且违背了回调的全部意义!考虑使用SendAsync相反(然后您仍然需要检查 BytesTransferred 属性)。

关于C# Socket.Send() : does it send all data or not?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49622057/

相关文章:

c# - 原生 C++ 还是 .NET for Business App?

java - 使用 HttpResponse 对象时获取套接字已关闭错误

c - 'kill -9 进程 ID' 信号处理程序

python - 在 Python 中使用 SocketHandler 记录时捕获错误

c# - 如何通过名称或ID获取内容类型?

c# - 使用 Microsoft Graph 重置用户密码

c# - 如何在 MVC 中的 Ajax 发布后刷新我的局部 View ?

c# - MVC 5 IdentityDbContext 和 DbContext 事务

.net - Squirrel.Windows 的好替代品

.net - 如何在 Windows 10 Creators 上安装 .NET Framework 4.6.2?