尝试发送多个数据包时,Java地址已被使用

时间:2018-01-19 04:15:57

标签: java sockets udp datagram

我正在尝试制作一个包含客户端,中间主机和服务器的程序。客户端将数据包发送到主机,主机将其发送到服务器,然后服务器将数据包发送回发送给客户端的主机。这应该重复11次。 这是我的代码:

public class SimpleEchoClient {

DatagramPacket sendPacket, receivePacket;
DatagramSocket sendReceiveSocket;

public SimpleEchoClient()
{
   try {

      sendReceiveSocket = new DatagramSocket();
   } catch (SocketException se) {   // Can't create the socket.
      se.printStackTrace();
      System.exit(1);
   }
}


public byte[] createWriteByte() {
    byte[] msg = new byte[100];
    int position = 2;
    Path path = Paths.get("test.txt");
    String fileName = path.getFileName().toString();

    //In datagrampackets, our data needs to be converted into bytes
    msg = new byte[100]; 
    msg[0] = 0x00;
    msg[1] = 0x02;

    for(int i=0; i<fileName.getBytes().length; i++) {
        msg[position] = fileName.getBytes()[i];
        position++;
    }

    msg[position] = 0x00;

    String mode = "netascii";

    position++;
    for(int i = 0; i < mode.getBytes().length; i++) {
        msg[position] = mode.getBytes()[i];
        position++;
    }
    msg[position] = 0;
    return msg;
}


public byte[] createReadByte() {
    byte[] msg = new byte[100];
    int position = 2;
    Path path = Paths.get("test.txt");
    String fileName = path.getFileName().toString();

    //In datagrampackets, our data needs to be converted into bytes
    msg = new byte[100]; 
    msg[0] = 0x00;
    msg[1] = 0x01;

    for(int i=0; i<fileName.getBytes().length; i++) {
        msg[position] = fileName.getBytes()[i];
        position++;
    }

    msg[position] = 0x00;

    String mode = "netascii";

    position++;
    for(int i = 0; i < mode.getBytes().length; i++) {
        msg[position] = mode.getBytes()[i];
        position++;
    }
    msg[position] = 0;
    return msg;
}

public void sendAndReceive(boolean checkRead)
{
        Path path = Paths.get("test.txt");
        String fileName = path.getFileName().toString();

        //In datagrampackets, our data needs to be converted into bytes
        byte[] msg;
        if(checkRead) {
            msg = createReadByte();
            checkRead = false;
        }else{
            msg = createWriteByte();
            checkRead = true;
        }

        String str = new String(msg);
        System.out.println(str);
        System.out.println("Hello");
        System.out.println(msg);

       try {
          sendPacket = new DatagramPacket(msg, msg.length,
                                          InetAddress.getLocalHost(), 5000);
       } catch (UnknownHostException e) {
          e.printStackTrace();
          System.exit(1);
       }

       try {
          sendReceiveSocket.send(sendPacket);
       } catch (IOException e) {
          e.printStackTrace();
          System.exit(1);
       }

    sendReceiveSocket.close();

    try {
        Thread.sleep(5000);
    } catch (InterruptedException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
       System.out.println("Client: Packet sent.\n");
       //NOW TO RECEIVE THE DATA
       DatagramSocket receiveSocket = null;
    try {
        receiveSocket = new DatagramSocket(5000);
    } catch (SocketException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
       byte data[] = new byte[4];
       receivePacket = new DatagramPacket(data, data.length);

       try {
          // Block until a datagram is received via sendReceiveSocket.  
          receiveSocket.receive(receivePacket);
       } catch(IOException e) {
          e.printStackTrace();
          System.exit(1);
       }

       // Process the received datagram.
       for(int j =0; j < data.length; j++) {
            System.out.println(data[j] & 0xff);
        }

       // We're finished, so close the socket.
       sendReceiveSocket.close();

}

public static void main(String args[])
{
    boolean checkRead = true;
    int count =0;
    for(int i = 0; i<10; i++) {
        System.out.println("Count:" + count);
        SimpleEchoClient c = new SimpleEchoClient();
        c.sendAndReceive(checkRead);
    }
}
}


public class IntermediateHost {

DatagramSocket receiveFromClient, receiveFromServer;
DatagramPacket receiveClientPack, sendClientPacket, receiveServerPacket, sendServerPacket;  

public IntermediateHost() {
    try {
        receiveFromClient = new DatagramSocket(5000);
    } catch (SocketException e) {
        e.printStackTrace();
    }
}

public void receiveAndEcho() {
    byte [] b = new byte[100];

    //When we receive the packet we need to store it in a datagrampacket which is initally empty
    receiveClientPack = new DatagramPacket(b, b.length);

    InetAddress  ip = null;
    try {
        receiveFromClient.receive(receiveClientPack);
        ip = InetAddress.getByName("localhost");
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    String message = new String(b);
    System.out.println(message);
    System.out.println(b);


    int port = 3001;

    sendClientPacket = new DatagramPacket(b, b.length, ip, port);
    try {
        receiveFromClient.send(sendClientPacket);
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    receiveFromClient.close();

    //SEND BACK TO THE CLIENT
    try {
        Thread.sleep(5000);
        receiveFromServer = new DatagramSocket(3001);
    } catch (InterruptedException | SocketException e1) {
        e1.printStackTrace();
    }

    byte [] b1 = new byte[4];

    //When we receive the packet we need to store it in a datagrampacket which is initally empty
    receiveServerPacket = new DatagramPacket(b1, b1.length);

    //This method will wait for the incoming packet and it will copy all values from that packet
    //into receiveClientPack..so at this point the byte array will not be empty
    try{
        receiveFromServer.receive(receiveServerPacket);
    }catch (Exception e) {
        System.out.println(e);
    }

    for(int i =0;i < b1.length; i++) {
        System.out.println(b1[i] & 0xff);
    }

    InetAddress ip1 = null;
    try {
        ip1 = InetAddress.getLocalHost();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
    int port1 = 5000;

    sendServerPacket = new DatagramPacket(b1, b1.length, ip1, port1);
    try {
        receiveFromServer.send(sendServerPacket);
    } catch (IOException e) {
        e.printStackTrace();
    }
    receiveFromServer.close();
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}


public static void main(String args[]) throws IOException, InterruptedException {
    while(true) {
    IntermediateHost inter = new IntermediateHost();
    inter.receiveAndEcho();
    }
}

}

public class SimpleEchoServer {

DatagramPacket sendPacket, receivePacket;
DatagramSocket sendSocket, receiveSocket;

public SimpleEchoServer()
{
   try {

      sendSocket = new DatagramSocket();

      receiveSocket = new DatagramSocket(3001);

   } catch (SocketException se) {
      se.printStackTrace();
      System.exit(1);
   } 
}

public byte[] sendBackRead() {
    byte [] bytesToSend = new byte[4];
    bytesToSend[0] = 0x00;
    bytesToSend[1] = 0x03;
    bytesToSend[2] = 0x00;
    bytesToSend[3] = 0x01;

    return bytesToSend;
}

public byte[] sendBackWrite() {
    byte [] bytesToSend = new byte[4];
    bytesToSend[0] = 0x00;
    bytesToSend[1] = 0x04;
    bytesToSend[2] = 0x00;
    bytesToSend[3] = 0x00;

    return bytesToSend;
}

public boolean checkRead(byte[] msg) {
    if(msg[1] == 1) {
        return true;
    }
    return false;
}

public boolean checkWrite(byte[] msg) {
    if(msg[1] == 2) {
        return true;
    }
    return false;
}

public void receiveAndEcho() throws UnknownHostException
{

   byte data[] = new byte[100];
   receivePacket = new DatagramPacket(data, data.length);
   System.out.println("Server: Waiting for Packet.\n");

   try {        
      System.out.println("Waiting..."); // so we know we're waiting
      receiveSocket.receive(receivePacket);
   } catch (IOException e) {
      System.out.print("IO Exception: likely:");
      System.out.println("Receive Socket Timed Out.\n" + e);
      e.printStackTrace();
      System.exit(1);
   }
   boolean checkRead = checkRead(data);
   boolean checkWrite = checkWrite(data);
    String message = new String(data);
    System.out.println(message);
    receiveSocket.close();


   // Slow things down (wait 5 seconds)
   try {
       Thread.sleep(5000);
   } catch (InterruptedException e ) {
       e.printStackTrace();
       System.exit(1);
   }
   byte[] bytesToSend = null;
   System.out.println(data[1]);
   if(checkRead) {
       bytesToSend = sendBackWrite();
   }else if(checkWrite) {
       bytesToSend = sendBackRead(); 
   }

    for(int i =0;i < bytesToSend.length; i++) {
        System.out.println(bytesToSend[i] & 0xff);
    }

    InetAddress ip = InetAddress.getLocalHost();

    sendPacket = new DatagramPacket(bytesToSend, bytesToSend.length,
                            ip, 3001);


   // Send the datagram packet to the client via the send socket. 
   try {
      sendSocket.send(sendPacket);
   } catch (IOException e) {
      e.printStackTrace();
      System.exit(1);
   }

   System.out.println("Server: packet sent");

   // We're finished, so close the sockets.
   sendSocket.close();
   receiveSocket.close();
}

public static void main( String args[] ) throws UnknownHostException
{
    while(true) {
        SimpleEchoServer c = new SimpleEchoServer();
        c.receiveAndEcho();
    }
}
}

现在这个代码可以工作,如果我只发送一个数据包到主机,主机发送到服务器,从主机返回另一个数据包到客户端。但是当我尝试发送超过一个数据包我收到一个错误。为了发送多个数据包,我基本上在main中创建一个循环,简单地调用方法11次,然后在服务器和主机中放置一个while循环,让它连续运行以等待数据包。要查看它运行一次,只需消除所有三个类的main函数中的while循环。

非常感谢有关如何修复此错误的任何帮助!谢谢!

1 个答案:

答案 0 :(得分:1)

每次调用SimpleEchoClient c = new SimpleEchoClient();时,您的代码都会尝试在端口5000上创建客户端。由于您已在同一端口上运行客户端,因此抛出异常。

所以只做一次并发送数据包11次。

public static void main(String args[])
{
    boolean checkRead = true;
    int count =0;
    SimpleEchoClient c = new SimpleEchoClient();
    for(int i = 0; i<=10; i++) {
        System.out.println("Count:" + count);      
        c.sendAndReceive(checkRead);
    }
}

检查我如何将循环条件更改为<=10以确保发送了11个数据包。