0

I'm getting the following exception (java.net.BindException: Address already in use) for some reason, eventhough I'm incrementing the port # before starting a new socket with it. This exception did not occur to me before using threads.

The sender should send parts of a file (each part using a new socket) to the receiver. The program was working and all the parts were received without using threads.

Now only the first part of the file is received at the receiver as the server does not create any sockets after the first one.

Also, these port #s are not used as they all did work before I started using threading.

I'm new to threading so I know I might be using it wrong.

Thanks in Advance!

Server Class:

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

} The ServerThread class:

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

    }
}

}

Client Class:

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

} Stack trace:

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
    Post the full stacktrace. Check that no other process is bound to the ports you're trying. – Sotirios Delimanolis Jun 20 '14 at 23:09
  • 1
    you're actually not really using threads the right way: your run method is not supposed to have an argument and you don't want to call it manually (like you did in the constructor), it's invoked automatically when you call start(). So what happens here? You create a new ServerThread-instance, wich calls your run(int por) method, wich will block until a datagram is received. Maybe your problem is located in another part of your program? Please post your stacktrace and more code – xmoex Jun 20 '14 at 23:17
  • you really need to provide more information on this topic, otherwise no one can help you. people won't waste their time in guessing what might be wrong when you could easily show them whats the problem. Helping people can be a lot of fun, but if there's lack of information it's just boring and nobody will do it. – xmoex Jun 20 '14 at 23:34
  • Now you're not even using the port to create the `DatagramSocket`. They all default to `0` in this case. – Sotirios Delimanolis Jun 21 '14 at 00:20
  • @SotiriosDelimanolis The problem was fixed by removing s.start() and running the thread using the run() method from inside the thread's constructor. Thanks for your help! – user3761646 Jun 21 '14 at 01:11
  • Please make sure you understand how a `Thread` object and an actual thread work together. – Sotirios Delimanolis Jun 21 '14 at 01:15
  • i can just emphasize what @SotiriosDelimanolis said, maybe this site: http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html would be a good start. if you don't use s.start() then you simply don't have a separate thread running, instead it's just the main thread descending into your custom run method... – xmoex Jun 21 '14 at 16:37

1 Answers1

1
  1. you are not using threads here. you start your server in the constructor.
  2. when you call s.start();, you are calling a stub method of Thread since its run method has different signature, you need to override it, not overload it, see difference here.
  3. other softwares can use your ports also. you need to check if its free, not just use it
Community
  • 1
  • 1
Dima
  • 8,586
  • 4
  • 28
  • 57
  • i don't think this code actually reaches s.start()... the custom run method calls DataGramm.recieve() wich will block until a DataGram arrives (wich i assume is not the case...) – xmoex Jun 20 '14 at 23:32
  • I really appreciate everyone's help. The problem was fixed by removing s.start() (since removing run() from the constructor didn't work) and having the thread to run just by calling the thread's constructor. Again I can't thank any of you guys enough. @xmoex – user3761646 Jun 21 '14 at 01:12