我在客户端和服务器上都有一个单独的线程,它们正在向/从套接字读取/写入数据.
I have a separate thread on both client and server that are reading/writing data to/from a socket.
我正在使用同步 TcpClient im(如文档中所建议):https://msdn.microsoft.com/cs-cz/library/system.net.sockets.tcpclient%28v=vs.110%29.aspx
I am using synchronous TcpClient im (as suggested in documention): https://msdn.microsoft.com/cs-cz/library/system.net.sockets.tcpclient%28v=vs.110%29.aspx
当连接关闭时 .Read()/.Write() 抛出异常.这是否意味着当 .Write() 方法没有抛出数据被正确传递给对方时,或者我是否需要实现自定义 ACK 逻辑?
When connection is closed .Read()/.Write() throws an exception. Does it mean that when .Write() method does not throw the data were delivered correctly to the other party or do I need to implement custom ACK logic?
我阅读了 Socket 和 TcpClient 类的文档,但没有一个描述这种情况.
I read documentation for both Socket and TcpClient class and none of them describe this case.
返回 send()
调用意味着(或您使用的任何包装器,如 Socket
或TcpClient
) 在流式传输、阻塞 Internet 套接字上是将字节放置在发送机器的缓冲区中.
All that a returning send()
call means (or any wrapper you use, like Socket
or TcpClient
) on a streaming, blocking internet socket is that the bytes are placed in the sending machine's buffer.
MSDN Socket.Send()
:
成功完成 Send 方法意味着底层系统有空间来缓冲网络发送的数据.
A successful completion of the Send method means that the underlying system has had room to buffer your data for a network send.
还有:
成功完成发送并不表示数据已成功传送.
The successful completion of a send does not indicate that the data was successfully delivered.
对于 .NET,底层实现是 WinSock2,文档:send():
For .NET, the underlying implementation is WinSock2, documentation: send():
成功完成发送函数并不表示数据已成功传递并接收到接收者.该函数仅表示数据发送成功.
The successful completion of a send function does not indicate that the data was successfully delivered and received to the recipient. This function only indicates the data was successfully sent.
对 send()
的调用返回并不不意味着数据已成功传送到另一端并被消费应用程序读取.
A call to send()
returning does not mean the data was successfully delivered to the other side and read by the consuming application.
当数据没有被及时确认,或者对方发送 RST 时,Socket
(或任何包装器)将处于故障状态,使 下一个 send()
或 recv()
失败.
When data is not acknowledged in time, or when the other party sends a RST, the Socket
(or whichever wrapper) will become in a faulted state, making the next send()
or recv()
fail.
所以为了回答你的问题:
So in order to answer your question:
是不是说.Write()方法不抛出数据被传递正确发送给对方还是我需要实现自定义 ACK 逻辑?
Does it mean that when .Write() method does not throw the data were delivered correctly to the other party or do I need to implement custom ACK logic?
不,它没有,是的,您应该 - 如果知道另一方已阅读该特定消息对您的应用程序很重要.
No, it doesn't, and yes, you should - if it's important to your application that it knows another party has read that particular message.
例如,如果服务器发送的消息指示客户端上的某种状态更改,客户端必须应用该更改以保持同步,就会出现这种情况.如果客户端不确认该消息,则服务器无法确定客户端具有最新状态.
This would for example be the case if a server-sent message indicates a state change of some sort on the client, which the client must apply to remain in sync. If the client doesn't acknowledge that message, the server cannot know for certain that the client has an up-to-date state.
在这种情况下,您可以更改协议,以便某些消息具有接收者必须返回的必需响应.请注意,实现应用程序协议非常容易出错.如果您愿意,可以使用 状态机,对于服务器和客户端.
In that case you could alter your protocol so that certain messages have a required response which the receiver must return. Do note that implementing an application protocol is surprisingly easy to do wrong. If you're inclined, you could implement having various protocol-dictated message flows using a state machine, for both the server and the client.
当然还有其他解决方案可以解决该问题,例如为每个状态提供一个唯一标识符,在尝试涉及该状态的任何操作之前与服务器进行验证,从而触发较早失败同步的重试.
Of course there are other solutions to that problem, such as giving each state a unique identifier, which is verified with the server before attempting any operation involving that state, triggering the retry of the earlier failed synchronization.
另见 如何检查 TCP 发送缓冲区的容量以确保数据传输,查明是否通过 tcp 发送了一条消息,C 套接字:发送是否等待接收结束?
这篇关于TcpClient 写方法是否保证数据传递到服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!