java 数据报套接字上的 setSotimeout

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7860904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:44:59  来源:igfitidea点击:

setSotimeout on a datagram socket

javasocketsdatagramsocket-timeout-exception

提问by Wasi

The server acts like an echo server. The clients sends 10 packets to server (1 sec of gap)

服务器就像一个回声服务器。客户端向服务器发送 10 个数据包(间隔 1 秒)

When Client receives packets from the server, sometimes the packets are lost.

Client在收到服务器发来的数据包时,有时会丢失数据包。

So the client has to wait for up to one second for the packet to arrive. If the packet does not arrive in 1 second then the client should continue sending the other packets.

因此,客户端最多需要等待一秒钟才能收到数据包。如果数据包未在 1 秒内到达,则客户端应继续发送其他数据包。

How would i use .setSoTimeout to achieve this?

我将如何使用 .setSoTimeout 来实现这一目标?

Code:

代码:

import java.io.*;
import java.net.*;
import java.util.*;
/*
* Client to process ping requests over UDP.
*/
public class PingClient
{
    private static final int AVERAGE_DELAY = 100; // milliseconds
    public static void main(String[] args) throws Exception
    {
// Get command line argument.
        int port = Integer.parseInt(args[1]);//specified as argument
// Create random number generator for use in simulating
// packet loss and network delay.
        System.out.println("Port "+port);
// Create a datagram socket for receiving and sending UDP packets
// through the port specified on the command line.
        DatagramSocket socket = new DatagramSocket(1234);

    int i=0;
        for(i=0;i<10;i++)
    {
    byte[] buf = new byte[1024] ;
    Calendar cal=Calendar.getInstance();
    String ping="Ping "+ i +" "+cal.getTimeInMillis()+"\r\n";
    buf=ping.getBytes("UTF-8");
    InetAddress address = InetAddress.getByName(args[0]);
    System.out.println("Name "+args[1]);
    DatagramPacket packet = new DatagramPacket(buf, buf.length, 
                                       address, port);
    packet.setData(buf);
    socket.send(packet);
    Thread.sleep( 10* AVERAGE_DELAY);//1 sec

    DatagramPacket server_response = new DatagramPacket(new byte[1024], 1024);
    // Block until the host receives a UDP packet.

        socket.setSoTimeout(1000); //I don't know how to use this
        socket.receive(server_response);

    // Print the recieved data.

        printData(server_response);

}   
}

private static void printData(DatagramPacket request) throws Exception
    {
// Obtain references to the packet's array of bytes.
    byte[] buf = request.getData();
// Wrap the bytes in a byte array input stream,
// so that you can read the data as a stream of bytes.
    ByteArrayInputStream bais = new ByteArrayInputStream(buf);
// Wrap the byte array output stream in an input stream reader,
// so you can read the data as a stream of characters.
    InputStreamReader isr = new InputStreamReader(bais);
// Wrap the input stream reader in a bufferred reader,
// so you can read the character data a line at a time.
// (A line is a sequence of chars terminated by any combination of \r and \n.)
    BufferedReader br = new BufferedReader(isr);
// The message data is contained in a single line, so read this line.
    String line = br.readLine();
// Print host address and data received from it.
    System.out.println(
        "Received from " +
        request.getAddress().getHostAddress() +
        ": " +
        new String(line) );
    }

}

}

回答by JB Nizet

The javadoc for setSoTimeoutsays:

setSoTimeoutjavadoc说:

With this option set to a non-zero timeout, a call to receive() for this DatagramSocket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the DatagramSocket is still valid.

将此选项设置为非零超时后,对此 DatagramSocket 的 receive() 调用将仅阻塞这段时间。如果超时到期,则会引发 java.net.SocketTimeoutException,但 DatagramSocket 仍然有效。

So, if you want to send packets if no response has been received after 1 second, you just have to use

所以,如果你想在 1 秒后没有收到响应的情况下发送数据包,你只需要使用

socket.setSoTimeout(1000L);
boolean continueSending = true;
int counter = 0;
while (continueSending && counter < 10) {
    // send to server omitted
    counter++;
    try {
        socket.receive(packet);
        continueSending = false; // a packet has been received : stop sending
    }
    catch (SocketTimeoutException e) {
        // no response received after 1 second. continue sending
    }
}