设置套接字接收超时
Posted
技术标签:
【中文标题】设置套接字接收超时【英文标题】:set timeout for socket receive 【发布时间】:2012-04-20 19:19:24 【问题描述】:我想向服务器发送数据,然后等待一分钟的应答,然后关闭套接字。
怎么做?
DatagramPacket sendpack = new ......;
socket.send(pack);
DatagramPacket recievepack = new .....;
//wait 1 minute
socket.recieve(buf);
//wait 1 minute
socket.close();
【问题讨论】:
您是否需要等待一分钟或数据在套接字上可用?如果您想等待一整分钟,我会使用 sleep 或 usleep 功能。这些将在一段时间内到期,然后再继续。如果您正在等待数据,我会查看 select 函数,它允许您等待数据到达或一段时间到期,以先到者为准。 @Glenn 睡眠可能会浪费一分钟。如果数据在一秒钟后到达怎么办?您认为 的读取超时究竟是什么? 【参考方案1】:为了澄清 EJP 的评论,这就是他所说的“缺少 break
”导致 SocketException。
String group = "224.0.0.0";
int port = 5000;
MulticastSocket recvSock = new MulticastSocket(port);
recvSock.joinGroup(InetAddress.getByName(group));
recvSock.setSoTimeout(1000);
while(true)
try
recvSock.receive(in);
catch (SocketTimeoutException e)
break; // Closing here would cause a SocketException
// Move the close() outside the try catch bloock
recvSock.leaveGroup(InetAddress.getByName(group));
recvSock.close();
【讨论】:
【参考方案2】:如果你使用DatagramSocket,或者Socket你可以使用,
socket.setSoTimeout(1000);
//the value is in milliseconds
有关任何详细信息,您应该查看DatagramSocket javadoc 或Socket javadoc。
【讨论】:
Socket.setSoTimeout
也存在。【参考方案3】:
你可以试试这个。根据您的场景需要更改套接字的超时时间!此代码将发送一条消息,然后等待接收消息,直到达到超时!
DatagramSocket s;
try
s = new DatagramSocket();
byte[] buf = new byte[1000];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
InetAddress hostAddress = InetAddress.getByName("localhost");
String outString = "Say hi"; // message to send
buf = outString.getBytes();
DatagramPacket out = new DatagramPacket(buf, buf.length, hostAddress, 9999);
s.send(out); // send to the server
s.setSoTimeout(1000); // set the timeout in millisecounds.
while(true) // recieve data until timeout
try
s.receive(dp);
String rcvd = "rcvd from " + dp.getAddress() + ", " + dp.getPort() + ": "+ new String(dp.getData(), 0, dp.getLength());
System.out.println(rcvd);
catch (SocketTimeoutException e)
// timeout exception.
System.out.println("Timeout reached!!! " + e);
s.close();
catch (SocketException e1)
// TODO Auto-generated catch block
//e1.printStackTrace();
System.out.println("Socket closed " + e1);
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
【讨论】:
一秒对于读取超时来说太短了。由于缺少break
,一旦发生超时,此代码将抛出SocketException: socket closed
。并非所有SocketExceptions
都表示套接字已关闭。以上是关于设置套接字接收超时的主要内容,如果未能解决你的问题,请参考以下文章