2014-07-14 220 views
0

我使用DataOutputStream在网络上这样的传输数据:等待套接字数据传输

Socket socket = new Socket(ipAddress, port); 
DataOutputStream dataOutputStream = new DataOutputStream(
        socket.getOutputStream()); 

dataOutputStream.writeBytes("Stackoverflow"); 
// ... 
System.exit(0); 

如果我的应用程序终止太早,传输将被中止,因此失败,因为不是所有的数据都有在那时已经发送。

为了解决这个问题,我可以手动等待一段时间终止前:

try 
{ 
    Thread.sleep(1000); 
} catch (InterruptedException e) 
{ 
    e.printStackTrace(); 
} 

然而,这种解决方案是坏的。在终止我的应用程序之前,是否有一些确保所有数据已经​​发送的“最佳实践”方法?

编辑:
我无权访问服务器代码。

+0

在网络代码中添加睡眠并不能完成任何操作。只要您正确关闭插座,数据就会到达。你确定问题不在另一端吗? – EJP

+0

问题可能确实存在于另一端,但仍可能有解决此问题的方法。 – BullyWiiPlaza

回答

0

默认情况下,socket.close()应导致正常的TCP连接关闭。在该过程中,TCP堆栈将未确认的数据传送给对等体。

dataOutputStream.flush(); 
socket.close(); 

如果您已将SO_LINGER设置为零,则不起作用。 替代方案是使用socket.shutdownOutput()

dataOutputStream.flush(); 
socket.shutdownOutput(); 
+0

这两个建议都不起作用,它仍然停止太早 – BullyWiiPlaza

+0

奇怪。你确定当你调用flush()时TCP连接仍然打开吗?并且所有的数据已经写入dataOutputStream? – SKi

+0

是的。我尝试调用'socket.close()'和'socket.shutdownOutput()',就像您在所有'DataOutputStream'写入后提示的一样,但都未能等到所有内容都发送完毕。 – BullyWiiPlaza

1

如果我的应用程序终止太早,传输将被中止,因此自()不是所有的数据已发送尚未冲洗的执行后失效。

数据是无缓冲的,因此每次写入都立即发送数据。在你的情况下,flush()没有做任何事情。

DataOutputStream.flush()

public void flush() throws IOException { 
    out.flush(); 
} 

调用OutputStream.flush()

public void flush() throws IOException { 
} 

是否有确保所有数据已终止前已发送的一些 “最佳实践” 的方式我应用?

确保数据已发送的最佳方式是等待答复。让另一端发回一条消息说它已收到它,并且您可以知道已收到数据。

顺便说一句当你完成一个可关闭的资源时,最好的做法是关闭它。

+0

是的,我认为'flush()'也没有做什么。问题在于我不知道如何访问服务器代码。我不确定我的套接字是否已经强制使用tcp连接。关于代码的任何提示我都应该尝试? – BullyWiiPlaza

+0

@ user3764804我认为您需要更好地理解问题,因为您的写入应该发送数据,并且不需要使用close(),但它可以确保不再需要它。 –

相关问题