Java 套接字TCP连接写入失败

Java 套接字TCP连接写入失败,java,sockets,tcp,Java,Sockets,Tcp,我通过套接字代码进行tcp通信,如: public void openConnection() throws Exception { socket = new Socket(); InetAddress iNet = InetAddress.getByName("server"); InetSocketAddress sock = new InetSocketAddress(iNet, Integer.parseInt(port)); socket.connect(soc

我通过套接字代码进行tcp通信,如:

public void openConnection() throws Exception
{
   socket = new Socket();
   InetAddress iNet = InetAddress.getByName("server");
   InetSocketAddress sock = new InetSocketAddress(iNet, Integer.parseInt(port));
   socket.connect(sock, 0);

   out = new PrintWriter(socket.getOutputStream(), true);
   in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
发送方法为:

synchronized void send(String message)
{
 try
 {
    out.println(message);
 }
 catch (Exception e)
 {
    throw new RuntimeException(this.getClass() + ": Error Sending Message: "
        + message, e);
 }
}
这会在套接字上写入消息,并通过tcp进行通信。(非阻塞呼叫)


我的疑问是,我们如何通过java代码确定此数据包是否成功发送或丢弃,原因是什么?

TCP提供了与端点的可靠通信。如果没有错误,则收到消息。TCP上的wikipedia页面声明:

TCP提供可靠、有序且经过错误检查的流传递 在连接到本地计算机的计算机上运行的程序之间的八进制数 局域网、内部网或公共互联网


如果通信失败,则可以检查已引发的特定异常。您应该查看以确定引发的特定异常及其原因。为了帮助实现这一点,更具体地处理异常非常有用(单独处理特定类型的异常,而不仅仅是捕获
异常
).

TCP确认表示数据被推送到TCP/IP堆栈的另一端&这不一定意味着接收方应用程序已经处理了数据。在windows/linux中,成功发送完成表示缓冲区被复制到内核模式套接字缓冲区。
您可以尝试将套接字缓冲区设置为零,这使得TCP/IP堆栈仅在收到缓冲区的确认后才能完成发送调用。这种情况至少在windows中发生&在java中不能假设这种行为。

你应该建立一个协议,接收者应该处理并确认收到每条消息。@ShaneWalti TCP已经做到了。是的,从技术上讲确实如此,但在实践中,你从未见过有人在TCP/IP之上建立一个没有自己消息的协议确认机制。HTTP没有自己的消息确认机制。响应是请求的结果,而不是对请求的确认。同样,服务器也不希望收到它发送的响应的接收确认。与TCP相比,TCP提供了明确的ACK消息,只与确认信息已被接收有关。不过,了解这种“可靠性”的限制非常重要。TCP的可靠性是从一个TCP堆栈到另一个TCP堆栈。一个TCP端点与另一个TCP端点通信。我真的不知道在什么情况下,TCP通道可能有一个非TCP端点。如果您成功地生成了这些数据,那么合法的TCP端点将很快停止传输和重新传输相同的数据,因为它会认为这些数据在传输过程中丢失。我的意思是,这种可靠性刚好达到TCP级别,那么在应用程序中执行的任何操作都是另一回事。有些人(可能不是你)误解了TCP的可靠性保证(请参阅),期望过高。“如果没有错误,则收到的消息”是非常不正确的。首先,没有消息。其次,由于缓冲和计时原因,错误仅在后续读取或写入时报告。因此,第三,不可能知道失败时收到了什么和没有收到什么。