TcpClient的write方法是否可以确保将数据传递到服务器? [英] Does TcpClient write method guarantees the data are delivered to server?

查看:52
本文介绍了TcpClient的write方法是否可以确保将数据传递到服务器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在客户端和服务器上都有一个单独的线程,它们正在向套接字读写数据.

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 )在阻止互联网流的流媒体上是将字节放置在发送机的缓冲区中.

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,文档:

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 (或任何包装器)将处于故障状态,从而使 next 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发送缓冲区的容量以确保数据传输 C套接字:发送是否等待recv结束?

这篇关于TcpClient的write方法是否可以确保将数据传递到服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆