2014-06-20 22 views
0

由於某些原因,我收到以下異常(java.net.BindException:地址已在使用中),儘管我在開始新建之前增加了端口#與它的插座。在使用線程之前,我不會發生這種異常。地址已經在使用,同時使用不同的端口號來創建套接字

發送方應該向接收方發送文件的部分內容(每個部分使用一個新的套接字)。程序正在運行,所有的部分都沒有使用線程。

現在在接收器中只接收到文件的第一部分,因爲服務器在第一部分之後沒有創建任何套接字。

此外,這些端口號並未使用,因爲它們在我開始使用線程之前都已經工作。

我是新的線程,所以我知道我可能會使用它錯誤。

在此先感謝!

服務器類:

public class Server { 
int port = 8500; 

public Server(int x) { 
    for (int i = 0; i < x; i++) { 
     ServerThread s = new ServerThread(port); 
     s.start(); 
     port++; 
    } 

} 

public static void main(String[] args) throws IOException { 

    DatagramSocket socket = new DatagramSocket(7499); 
    byte[] buffer = new byte[256]; 
    DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length); 
    socket.receive(receivePacket); 
    String message = new String(buffer, 0, receivePacket.getLength()); 
    int xyz = Integer.parseInt(message); 
    socket.close(); 
    Server server = new Server(xyz); 

    try { 
     FileJoin f = new FileJoin(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    System.exit(0); 
} 

} 的ServerThread類:

public class ServerThread extends Thread { 
private FileEvent fileEvent1 = null; 
private int port; 

ServerThread(int port) { 

    this.port = port; 
    run(); 
} 

public void run() { 
    try { 
     createAndListenSocket(this.port); 
    } catch (ClassNotFoundException | InterruptedException | IOException e) { 

     e.printStackTrace(); 
    } 
} 

public void createAndListenSocket(int portx) throws InterruptedException, 
     IOException, ClassNotFoundException { 

    DatagramSocket socket1 = new DatagramSocket(portx); 

    byte[] incomingData1 = new byte[1024 * 1000 * 50]; 

    DatagramPacket incomingPacket1 = new DatagramPacket(incomingData1, 
      incomingData1.length); 

    socket1.receive(incomingPacket1); 

    byte[] data1 = incomingPacket1.getData(); 

    ByteArrayInputStream in1 = new ByteArrayInputStream(data1); 

    ObjectInputStream is1 = new ObjectInputStream(in1); 

    fileEvent1 = (FileEvent) is1.readObject(); 

    if (fileEvent1.getStatus(0).equalsIgnoreCase("Error")) { 

     System.exit(0); 

    } 

    createAndWriteFile(); // writing the file to hard disk 

    InetAddress IPAddress = incomingPacket1.getAddress(); 

    int porty = incomingPacket1.getPort(); 

    String reply = "The file was successfuly saved. "; 

    byte[] replyBytea = reply.getBytes(); 

    DatagramPacket replyPacket = 

    new DatagramPacket(replyBytea, replyBytea.length, IPAddress, porty); 

    socket1.send(replyPacket); 

    Thread.sleep(3000); 

} 

public void createAndWriteFile() { 
    String outputFile1 = fileEvent1.getDestinationDirectory(0) 
      + fileEvent1.getFilename(0); 

    if (!new File(fileEvent1.getDestinationDirectory(0)).exists()) { 

     new File(fileEvent1.getDestinationDirectory(0)).mkdirs(); 

    } 

    File dstFile1 = new File(outputFile1); 

    FileOutputStream fileOutputStream1 = null; 

    try { 

     fileOutputStream1 = new FileOutputStream(dstFile1); 

     fileOutputStream1.write(fileEvent1.getFileData(0)); 

     fileOutputStream1.flush(); 

     fileOutputStream1.close(); 

     System.out.println("Output file : " + outputFile1 
       + " is successfully saved "); 

    } catch (FileNotFoundException e) { 

     e.printStackTrace(); 

    } catch (IOException e) { 

     e.printStackTrace(); 

    } 
} 

}

客戶端類:

public class Client { 

private FileEvent event1 = null; 
private String sourceFilePath = "D:/workspace/newUDP/Image.jpgPart"; 
private int filenum; 
private String destinationPath = "E:/UDPreceive/"; 
private int port = 8500; 

private String hostName = "127.0.0.1"; 

public Client() { 

} 

public void createConnection(int x) { 

    try { 
     InetAddress IPAddress = InetAddress.getByName(hostName); 
     for (int i = 0; i < x; i++) { 
      DatagramSocket socket1 = new DatagramSocket(); 

      byte[] incomingData = new byte[1024]; 

      event1 = getFileEvent(0); 

      ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 

      ObjectOutputStream os = new ObjectOutputStream(outputStream); 

      os.writeObject(event1); 

      byte[] data = outputStream.toByteArray(); 

      DatagramPacket sendPacket1 = new DatagramPacket(data, 
        data.length, IPAddress, port); 

      socket1.send(sendPacket1); 

      System.out.println("File sent from client"); 

      DatagramPacket incomingPacket = new DatagramPacket(
        incomingData, incomingData.length); 

      socket1.receive(incomingPacket); 

      String response = new String(incomingPacket.getData()); 

      System.out.println("Response from server:" + response); 

      port++; 
     } 

     Thread.sleep(2000); 

    } catch (UnknownHostException e) { 

     e.printStackTrace(); 

    } catch (SocketException e) { 

     e.printStackTrace(); 

    } catch (IOException e) { 

     e.printStackTrace(); 
    } catch (InterruptedException e) { 

     e.printStackTrace(); 

    } 

} 

public FileEvent getFileEvent(int i) { 

    FileEvent fileEvent = new FileEvent(); 
    sourceFilePath = sourceFilePath + filenum; 

    String fileName1 = sourceFilePath.substring(
      sourceFilePath.lastIndexOf("/") + 1, sourceFilePath.length()); 

    String path1 = sourceFilePath.substring(0, 
      sourceFilePath.lastIndexOf("/") + 1); 

    fileEvent.setDestinationDirectory(destinationPath, 0); 

    fileEvent.setFilename(fileName1, 0); 

    fileEvent.setSourceDirectory(sourceFilePath, 0); 

    File file1 = new File(sourceFilePath); 
    filenum++; 
    sourceFilePath = "D:/workspace/newUDP/Image.jpgPart"; 

    if (file1.isFile()) { 

     try { 

      DataInputStream diStream = new DataInputStream(
        new FileInputStream(file1)); 

      long len = (int) file1.length(); 

      byte[] fileBytes = new byte[(int) len]; 

      int read = 0; 

      int numRead = 0; 

      while (read < fileBytes.length 
        && (numRead = diStream.read(fileBytes, read, 

        fileBytes.length - read)) >= 0) { 

       read = read + numRead; 

      } 

      fileEvent.setFileSize(len, 0); 

      fileEvent.setFileData(fileBytes, 0); 

      fileEvent.setStatus("Success", 0); 

     } catch (Exception e) { 

      e.printStackTrace(); 

      fileEvent.setStatus("Error", 0); 

     } 

    } else { 

     System.out.println("path specified is not pointing to a file"); 

     fileEvent.setStatus("Error", 0); 

    } 

    return fileEvent; 

} 

public static void main(String[] args) throws IOException { 
    try { 
     FileSplit f = new FileSplit(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    try { 
     DatagramSocket socket = new DatagramSocket(); 
     String xyz = "" + FileSplit.getJ(); 
     System.out.println(xyz); 
     InetAddress serverAddress = InetAddress.getByName("127.0.0.1"); 

     byte[] sendBytes = xyz.getBytes(); 

     DatagramPacket sendPacket = new DatagramPacket(sendBytes, 
       sendBytes.length, serverAddress, 7499); 
     socket.send(sendPacket); 
     System.out.println(xyz); 
     Client client = new Client(); 

     client.createConnection(Integer.parseInt(xyz)); 
    } catch (IOException x) { 

    } 

    System.exit(0); 
} 

} 堆棧跟蹤:

java.net.BindException: Address already in use: Cannot bind 
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method) 
at java.net.DualStackPlainDatagramSocketImpl.bind0(Unknown Source) 
at java.net.AbstractPlainDatagramSocketImpl.bind(Unknown Source) 
at java.net.DatagramSocket.bind(Unknown Source) 
at java.net.DatagramSocket.<init>(Unknown Source) 
at java.net.DatagramSocket.<init>(Unknown Source) 
at java.net.DatagramSocket.<init>(Unknown Source) 
at pack.ServerThread.createAndListenSocket(ServerThread.java:32) 
at pack.ServerThread.run(ServerThread.java:24) 
+1

發佈完整的堆棧跟蹤。檢查沒有其他進程綁定到您嘗試的端口。 –

+1

你實際上並沒有真正以正確的方式使用線程:你的run方法不應該有一個參數,你不想手動調用它(就像你在構造函數中那樣),當你調用start() )。那麼這裏發生了什麼?你創建一個新的ServerThread實例,它會調用你的run(int por)方法,直到接收到一個數據報爲止。也許你的問題位於你程序的另一部分?請發佈您的stacktrace和更多代碼 – xmoex

+0

您確實需要提供有關此主題的更多信息,否則沒有人可以幫助您。人們不會浪費時間來猜測什麼可能是錯誤的,當你可以很容易地向他們展示什麼是問題。幫助人們可以非常有趣,但是如果缺乏信息,那就很無聊,沒有人會這樣做。 – xmoex

回答

1
  1. 你不使用線程在這裏。你在構造函數中啓動你的服務器。
  2. 當您撥打s.start();時,您打電話給stub method of Thread,因爲它的運行方法有不同的簽名,您需要覆蓋它,不要超載它,請參閱區別here
  3. 其他軟件也可以使用您的端口。你需要檢查它是否免費,而不僅僅是使用它
+0

我不認爲這個代碼實際上達到了s。 start()...自定義運行方法調用DataGramm.recieve()將阻塞,直到一個DataGram到達(我想這不是這種情況...) – xmoex

+0

你說得對,我只是解釋了代碼,運行時將阻塞... – Dima

+0

我真的很感謝大家的幫助。通過刪除s.start()(由於從構造函數中移除run()不起作用)並通過調用線程的構造函數來讓線程運行,從而解決了問題。我再次感謝你們中的任何一個。 @xmoex – user3761646

相關問題