【问题标题】:Reliable UDP in javajava中可靠的UDP
【发布时间】:2016-04-19 20:24:28
【问题描述】:

我正在完成使用 java 使 UDP 可靠的任务。如何添加超时和重新传输来处理被丢弃的数据报并添加序列号,以便客户端可以验证回复是否针对适当的请求??

这是客户端代码

import java.net.*;
import java.io.*;
public class EchoClient {
// UDP port to which service is bound
    public static final int SERVICE_PORT = 7;


// Max size of packet
public static final int BUFSIZE = 256;
public static void main(String args[]){
                 if (args.length != 1)
                 {
                         System.err.println ("Syntax - java EchoClient hostname");
                         return;
                  }
String hostname = args[0];
// Get an InetAddress for the specified hostname
    InetAddress addr = null;
        try
        {
            // Resolve the hostname to an InetAddr
            addr = InetAddress.getByName(hostname);
        }
        catch (UnknownHostException uhe)
        {
            System.err.println ("Unable to resolve host");
            return;
        }

        try
        {
            // Bind to any free port
            DatagramSocket socket = new DatagramSocket();

            // Set a timeout value of two seconds
            socket.setSoTimeout (2 * 1000);

            for (int i = 1 ; i <= 10; i++)
            {
                // Copy some data to our packet
                String message = "Packet number " + i ;
                char[] cArray = message.toCharArray();                  
                byte[] sendbuf = new byte[cArray.length];
                for (int offset = 0; offset < cArray.length ; offset++)
                {
                    sendbuf[offset] = (byte) cArray[offset];
                }

                // Create a packet to send to the UDP server
                DatagramPacket sendPacket = new DatagramPacket(sendbuf, cArray.length, addr, SERVICE_PORT);

                System.out.println ("Sending packet to " + hostname);

                // Send the packet
                socket.send (sendPacket);

                System.out.print ("Waiting for packet.... ");

                // Create a small packet for receiving UDP packets
                byte[] recbuf = new byte[BUFSIZE];
                DatagramPacket receivePacket = new DatagramPacket(recbuf, BUFSIZE);

                // Declare a timeout flag
                boolean timeout = false;

                // Catch any InterruptedIOException that is thrown
                // while waiting to receive a UDP packet
                try
                {
                    socket.receive (receivePacket);
                }
                catch (InterruptedIOException ioe)
                {
                    timeout = true;
                }

                if (!timeout)
                {
                    System.out.println ("packet received!");
                    System.out.println ("Details : " + receivePacket.getAddress() );

                    // Obtain a byte input stream to read the UDP packet
                    ByteArrayInputStream bin = new ByteArrayInputStream (
                      receivePacket.getData(), 0, receivePacket.getLength() );

                    // Connect a reader for easier access
                    BufferedReader reader = new BufferedReader ( 
                      new InputStreamReader ( bin ) );

                    // Loop indefinitely
                    for (;;)
                    {
                        String line = reader.readLine();

                        // Check for end of data
                        if (line == null)
                            break;
                        else
                            System.out.println (line);
                    }               
                }
                else
                {
                    System.out.println ("packet lost!");
                }

                // Sleep for a second, to allow user to see packet
                try
                {
                    Thread.sleep(1000);
                }catch (InterruptedException ie) {}
            }
        }
        catch (IOException ioe)
        {
            System.err.println ("Socket error " + ioe);
        }
    }
}

【问题讨论】:

  • UDP 被专门设置为不可靠。另一方面,TCP 被构建为可靠的。所以如果你想要可靠,你应该使用TCP
  • @ControlAltDel 这并不完全正确。人们经常通过在 UDP 之上创建自己的服务来利用 UDP 的性能提升。
  • 这很好,但我们可以向客户端添加一些功能以使其可靠,例如校验和或序列号和超时
  • @flkes 我认为 ControlAltDel 是正确的,人们确实创建了像 UDP 这样的协议,但 UDP 本身被设计为不可靠的。 UDP没有选项头,意味着客户端和服务器端没有空间添加序列号、缓冲区和窗口支持,这三个头是使TCP可靠的主要因素。
  • @M.N.N,我认为您不能添加它们,因为 UDP 没有空间让您添加额外的标头。您可以在两侧添加缓冲区或创建窗口,但只能在一定程度上提高可靠性。

标签: java


【解决方案1】:

您可以做的是在 UDP 消息正文中添加导入 TCP 标头(如序列号、窗口),使其更像 TCP。这是一个solution,可能会对您有所帮助。

【讨论】:

    猜你喜欢
    • 2011-09-25
    • 2017-05-10
    • 2011-11-11
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    相关资源
    最近更新 更多