【问题标题】:"BindException: Address already in use" exception when transferring file using java socket in a same pc在同一台电脑中使用 java 套接字传输文件时出现“BindException:地址已在使用”异常
【发布时间】:2016-10-11 16:19:45
【问题描述】:

我对 java 网络编程很陌生。我正在尝试编写一个可以通过网络传输文件的程序。我为发送者和接收者编写了两个单独的程序。并在我的电脑的两个单独的 Intellij 窗口中运行这两个程序。我在服务器套接字和接收器套接字中放置了相同的端口号。 IP 地址是本地主机。当我运行这两个程序时,这两个程序中的任何一个都会引发异常。

经过一番谷歌搜索后,我发现Java sockets: multiple client threads on same port on same machine? 问题,人们说在同一个端口运行两个程序是合法的。我还没有从两台不同的 PC 上测试这段代码。

所以我的问题是我错过了什么?我可以在我的电脑上同时运行这两个程序吗?

这是我写的代码 -

对于发件人--

public class Sender {
public static void main(String[] args) throws IOException
{
    String fileLocation;
    int portNo;
    portNo = 6000;
    fileLocation = "/files/A.cpp";
    Sender.send(portNo,fileLocation);
}
public static  void send(int portNo,String fileLocation) throws IOException
{

    FileInputStream fileInputStream = null;
    BufferedInputStream bufferedInputStream = null;

    OutputStream outputStream = null;
    ServerSocket serverSocket = null;
    Socket socket = null;
    try {
        serverSocket = new ServerSocket(portNo);
        System.out.println("Waiting for receiver...");
        try {
            socket = serverSocket.accept();
            System.out.println("Accepted connection : " + socket);

            File file = new File (fileLocation);
            byte [] byteArray  = new byte [(int)file.length()];
            fileInputStream = new FileInputStream(file);
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            bufferedInputStream.read(byteArray,0,byteArray.length); // copied file into byteArray

            //sending file through socket
            outputStream = socket.getOutputStream();
            System.out.println("Sending " + fileLocation + "( size: " + byteArray.length + " bytes)");
            outputStream.write(byteArray,0,byteArray.length);
            outputStream.flush();
            System.out.println("Done.");
        }
        finally {
            if (bufferedInputStream != null) bufferedInputStream.close();
            if (outputStream != null) bufferedInputStream.close();
            if (socket!=null) socket.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    finally {
        if (serverSocket != null) serverSocket.close();
    }
}
}

对于接收者 --

public class Receiver {

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


    String fileLocation,ipAddress;
    int portNo;
    ipAddress = "localhost";
    portNo = 6000;
    fileLocation = "/files/A.cpp";
    Receiver.receiveFile(ipAddress, portNo, fileLocation);


}
public static void receiveFile(String ipAddress,int portNo,String fileLocation) throws IOException
{
    int bytesRead=0;
    int current = 0;
    FileOutputStream fileOutputStream = null;
    BufferedOutputStream bufferedOutputStream = null;
    Socket socket = null;
    try {
        socket = new Socket(ipAddress,portNo);
        System.out.println("connected.");

        byte [] byteArray  = new byte [6022386];                    
        System.out.println("Please wait downloading file");

        InputStream inputStream = socket.getInputStream();
        fileOutputStream = new FileOutputStream(fileLocation);
        bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        bytesRead = inputStream.read(byteArray,0,byteArray.length);         

        current = bytesRead;
        do {
            bytesRead =inputStream.read(byteArray, current, (byteArray.length-current));
            if(bytesRead >= 0) current += bytesRead;
        } while(bytesRead > -1);
        bufferedOutputStream.write(byteArray, 0 , current);             

        System.out.println("File " + fileLocation  + " downloaded ( size: " + current + " bytes read)");
    } catch (IOException e) {
        e.printStackTrace();
    }
    finally {
        if (fileOutputStream != null) fileOutputStream.close();
        if (bufferedOutputStream != null) bufferedOutputStream.close();
        if (socket != null) socket.close();
    }
}
}

谢谢。

【问题讨论】:

  • 没有。您不能将两个不同的程序绑定到同一个端口。客户端和服务器必须使用不同的端口进行监听。
  • 你不能在同一台机器上有两个套接字侦听在同一个端口上,因此例外。

标签: java sockets exception port


【解决方案1】:

您的接收器不需要指定要使用的端口,将其留给操作系统(它会自动分配一个空闲临时端口号;端口号并不重要)。

改为使用 Socket.connect(SocketAddress) 方法将客户端套接字连接到服务器。使用服务器的 IP/名称加上使用的端口号指定套接字地址,例如:

InetAddress iadr = InetAddress.getByName("localhost");
SocketAddress sadr = new InetSocketAddress(iadr, portNo);
Socket socket = new Socket();
socket.connect(sadr);

这是您通常在指定端口连接到服务器的方式。未明确指定本地(客户端)端点。

当然,服务器必须已经在运行才能成功。

编辑:由于客户端端点是自动分配的,操作系统将为每个客户端分配一个免费端点,因此您可以在同一台机器上运行多个客户端(接收器)而不会发生任何冲突。

【讨论】:

    【解决方案2】:

    首先,两个 serverSocket 使用相同的端口是不可能的,因此如果您不运行 Sender 类两次,您的代码应该可以工作,您需要将您的类 Receiver_ 的名称更正为 Receiver 那么您的代码工作的步骤是:

    • 首先运行 Receiver Class(始终由服务器启动)
    • 然后运行 ​​Sender Class(这里是客户端)
    • 如果它不起作用,可能是因为另一个程序正在使用端口 6000,请尝试在两个类中将其更改为另一个,例如 9010

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多