设置套接字接收超时

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 都表示套接字已关闭。

以上是关于设置套接字接收超时的主要内容,如果未能解决你的问题,请参考以下文章

如何设置socket的Connect超时

python3套接字udp设置接受数据超时

ZMQ 套接字连接超时

poll() 在以 0 超时调用时接收传入数据

java-接收UDP包时设置超时函数java

即使设置了无限超时,Webrequest 也会超时