带有Go back N的Java UDP传输

时间:2015-03-06 03:15:46

标签: java sockets udp

我有一个简单的工作程序,可以使用UDP传输文件。但对于每个客户端和服务器,我有两个套接字,它们在一个端口发送数据并在另一个端口接收数据。

例如,我的客户端socket_out在端口9000发送数据包,并通过socket_in接收数据,该数据包在端口9001处侦听。我的服务器socket_in在端口9000处侦听并在端口9001发送ACK数据包。

现在我想简化设计,并且只使用一个端口号在每个客户端和服务器上接收和发送消息。例如,客户端和服务器程序都在端口9000发送和接收数据。

有可能吗?我该如何改变?我试图创建两个套接字用于发送和接收相同的端口号,但我总是得到这个错误:

  java.net.BindException: Address already in use

我用google搜索发现两个套接字无法共享相同的端口号。

添加代码: 发信人:

    public FileSender(String fileName, int unrelPort, String rcvFileName) {
    DatagramSocket socket_out_client, socket_in_client; 
    System.out.println("Start Sending " + fileName + " through port " +unrelPort + " as " + rcvFileName + ".");
    try {
        // create sockets
        socket_out_client = new DatagramSocket();
        socket_in_client = new DatagramSocket(unrelPort);

        // create input file

        File inputFile = new File(fileName);

        if (!inputFile.exists()) {
            System.err.println("Input file does not exist");
            System.exit(-1);
        }

        // create threads to process data
        InThread th_in = new InThread(socket_out_client,socket_in_client);
        OutThread th_out = new OutThread(socket_in_client, unrelPort, inputFile, rcvFileName);
        th_in.start();
        th_out.start();

    } catch (Exception e) {
        e.printStackTrace();
        System.exit(-1);
    }
}

接收器相同

2 个答案:

答案 0 :(得分:1)

端口号是网络数据包中嵌入的数字。一旦计算机的操作系统处理入站网络数据包,它就需要知道"哪个程序将包传递给输入。端口号用于在接收操作系统的端口到程序表中查找程序。

这就是为什么你不能从同一个端口读取两个程序的原因,因为这大致使操作系统无法确定数据包应该作为输入发送到哪两个程序中。

请注意,这不是导致端口冲突的唯一方法。你也可以在同一台机器上运行两个程序副本。

答案 1 :(得分:0)

首先,为什么在客户端创建两个套接字用于发送和接收,当您可以使用相同的socket_client发送和接收时。您可以通过创建两个用于发送的线程和一个用于使用相同socket_client接收的线程来完成此操作。

代码:类似这样的

 DatagramSocket sock = new DatagramSocket();
 new Thread(new Runnable() {

                @Override
                public void run() {
   try{
     //create packet
     //your logic 
     sock.send(packet); 
    }
   }catch(Exception e){}

             }       
            }).start();
System.out.println("Debug :: "+"thread 1 started");

new Thread(new Runnable() {

                @Override
                public void run() {
   try{
        //your logic
        sock.receive(packet)
    }
   }catch(Exception e){}

             }       
            }).start();
System.out.println("Debug :: "+"thread 2 started");