2

サーバーは、エコー サーバーのように機能します。クライアントはサーバーに 10 個のパケットを送信します (1 秒のギャップ)

クライアントがサーバーからパケットを受信すると、パケットが失われることがあります。

そのため、クライアントはパケットが到着するまで最大 1 秒待つ必要があります。パケットが 1 秒以内に到着しない場合、クライアントは他のパケットの送信を続行する必要があります。

これを達成するために .setSoTimeout をどのように使用しますか?

コード:

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) );
    }

}

4

1 に答える 1

12

setSoTimeoutのjavadoc には次のように書かれています。

このオプションをゼロ以外のタイムアウトに設定すると、この DatagramSocket に対する receive() の呼び出しは、この時間だけブロックされます。タイムアウトになると、java.net.SocketTimeoutException が発生しますが、DatagramSocket は引き続き有効です。

したがって、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
    }
}
于 2011-10-22T16:48:36.073 に答える