我有一个简单的表现糟糕的服务器(用Groovy编写)
ServerSocket ss = new ServerSocket(8889);
Socket s = ss.accept()
Thread.sleep(1000000)
我希望超时的客户端(因为服务器没有消耗它的输入)
Socket s = new Socket("192.168.0.106", 8889)
s.setSoTimeout(100);
s.getOutputStream.write( new byte[1000000] );
然而,这个客户端永远阻止。如何让客户端超时?
谢谢!
答案 0 :(得分:3)
你可以在它自己的线程中生成客户端并在其上旋转锁定/等待(超长)以返回。如果套接字成功,可能会使用 Future 对象获取返回值。
我确实认为Socket的SO_TIMEOUT设置只影响来自套接字的read(..)调用,而不是写入。
您可以尝试使用 SocketChannel (而不是Stream)并生成另一个也具有该Channel通道的线程。另一个线程可以在阻塞它的某个超时后异步关闭该通道。
答案 1 :(得分:1)
套接字超时是TCP级别,而不是应用程序级别。源机器TCP正在缓冲要发送的数据,目标机器网络堆栈正在确认收到的数据,因此没有超时。此外,不同的TCP / IP实现以不同方式处理这些超时。使用tcpdump(或wireshark如果你是如此不幸的话,看看线路上发生了什么:)你需要的是应用级别的ACK,即你需要在客户端和服务器之间定义协议。我无法评论Java包(您可能希望查看nio),但是通常会使用poll/select来处理该ACK的超时。
答案 2 :(得分:0)
无法获得超时,但如果写入尚未完成,您总是可以生成一个关闭连接的线程。