Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.net.BindException:地址已在使用中:无法绑定_Java_Sockets_Network Programming_Serversocket - Fatal编程技术网

java.net.BindException:地址已在使用中:无法绑定

java.net.BindException:地址已在使用中:无法绑定,java,sockets,network-programming,serversocket,Java,Sockets,Network Programming,Serversocket,对不起,我已经搜索过了,但似乎所有的答案都不能解决我的问题。我在尝试创建ServerSocket以答复多个客户端消息时遇到此错误 我的服务器代码: package Server; import java.net.*; import java.io.*; public class Server { public final static int defaultPort = 7; public static void main(String[] args) {

对不起,我已经搜索过了,但似乎所有的答案都不能解决我的问题。我在尝试创建ServerSocket以答复多个客户端消息时遇到此错误

我的服务器代码:

package Server;

import java.net.*;
import java.io.*;

public class Server {
    public final static int defaultPort = 7;

    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(defaultPort);            
            int i = 0;
            while (true) {
                try {
                    System.out.println("Server is running on port "
                            + defaultPort);
                    Socket s = ss.accept();
                    System.out.println("Client " + i + " connected");
                    RequestProcessing rp = new RequestProcessing(s, i);
                    i++;
                    rp.start();
                } catch (IOException e) {
                    System.out.println("Connection Error: " + e);
                }
            }
        } catch (IOException e) {
            System.err.println("Create Socket Error: " + e);
        } finally {

        }
    }
}

class RequestProcessing extends Thread {
    Socket channel;
    int soHieuClient;

    public RequestProcessing(Socket s, int i) {
        channel = s;
        clientNo = i;
    }

    public void run() {
        try {
            byte[] buffer = new byte[6000];
            DatagramSocket ds = new DatagramSocket(7);          
            while (true) {  
                DatagramPacket incoming = new DatagramPacket(buffer,
                        buffer.length);
                ds.receive(incoming);
                String theString = new String(incoming.getData(), 0,
                        incoming.getLength());
                System.out.println("Client " + clientNo 
                        + " sent: " + theString);
                if ("quit".equals(theString)) {
                    System.out.println("Client " + clientNo 
                            + " disconnected");
                    ds.close();
                    break;
                }
                theString = theString.toUpperCase();
                DatagramPacket outsending = new DatagramPacket(
                        theString.getBytes(), incoming.getLength(),
                        incoming.getAddress(), incoming.getPort());
                System.out.println("Server reply to Client "
                        + clientNo + ": " + theString);
                ds.send(outsending);
            }
        } catch (IOException e) {
            System.err.println(e);
        }

    }
}
和我的客户代码:

package Client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;

public class Client extends Object {
    public final static int serverPort = 7;

    public static void main(String[] args) {
        try {

            DatagramSocket ds = new DatagramSocket();
            InetAddress server = InetAddress.getByName("192.168.109.128");
            Socket s = new Socket("192.168.109.128", 7);            
            String theString = "";
            do {
                System.out.print("Enter message: ");
                InputStreamReader isr = new InputStreamReader(System.in);
                BufferedReader br = new BufferedReader(isr);
                theString = br.readLine();
                byte[] data = theString.getBytes();
                DatagramPacket dp = new DatagramPacket(data, data.length,
                        server, serverPort);

                ds.send(dp);
                System.out.println("Sent to server server: " + theString);

                byte[] buffer = new byte[6000];

                DatagramPacket incoming = new DatagramPacket(buffer,
                        buffer.length);
                ds.receive(incoming);
                System.out.print("Server reply: ");
                System.out.println(new String(incoming.getData(), 0, incoming
                        .getLength()));

            } while (!"quit".equals(theString));
            s.close();
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}
通过第一个客户端连接,它可以顺利工作。但是从第二个客户端,它抛出java.net.BindException:Address ready in use:Cannot bind。 第二个客户端也可以发送和接收消息,但客户端号仍然为0

Server is running on port 7
Client 0 connected
Server is running on port 7
Client 0 sent: msg 0
Server reply to Client 0: MSG 0
Client 1 connected
Server is running on port 7
java.net.BindException: Address already in use: Cannot bind
Client 0 sent: msg 1 <<-- this one is sent from client 1 but Client No is 0
Server reply to Client 0: MSG 1
服务器正在端口7上运行
客户端0已连接
服务器正在端口7上运行
客户端0已发送:消息0
服务器对客户端0的答复:消息0
客户端1已连接
服务器正在端口7上运行
java.net.BindException:地址已在使用中:无法绑定

客户端0已发送:msg 1因此,在
RequestProcessing.run
中,您决定忽略构造函数接收到的套接字,并在与正在侦听的端口相同的端口上打开DatagramSocket。你以为会发生什么事

class RequestProcessing extends Thread {
    Socket channel;
    int soHieuClient;

    public RequestProcessing(Socket s, int i) {
        // *****************
        // The processor should be using this socket to communicate
        // with a connected client *using TCP Streams*
        channel = s;
        clientNo = i;
    }

    public void run() {
       try {
           byte[] buffer = new byte[6000];
           // *****************************
           // But, instead of using the this.channel, your code
           // decides to ignore the TCP socket,
           // then open another UDP *"server-side like"* socket.
           // First time it's OK, but the second thread attempting
           // to open another DatagramSocket on the same port will fail.
           // It's like attempting to open two TCP ServerSockets on the
           // same port
           DatagramSocket ds = new DatagramSocket(7);  
[额外]

您需要决定要使用什么协议:如果您使用
ServerSocket
/
Socket
对,那么您可能需要TCP通信,因此不需要
DatagramSocket
s

如果您想要UDP通信,那么
服务器套接字
/
套接字
与您的方法几乎没有关系,您需要使用
数据报套接字
。构建它:

  • -而且只做一次
  • 然后用服务器地址和端口限定每个
    数据包
    
    请参阅Oracle网站上的教程

    每次在
    main
    服务器套接字上接收到新的客户端TCP连接时,都会启动RequestProcessing类的另一个实例。第一次启动RequestProcessing实例线程时,它成功绑定到UDP端口7。但是,第二个客户端连接,您尝试启动另一个RequestProcessing实例,而另一个实例已经存在。那是行不通的

    您可能应该修改您的协议,这样RequestProcessing类每次都会选择一个新端口,并向TCP套接字发回所选端口的信号

    但如果是我,我会这么做。为所有客户端提供一个RequestProcessing实例。假设您的UDP echo套接字只是将响应发送回数据包到达的地址,您只需要此类的一个实例。

    TCP解决方案:

    实用程序类(我懒得在多个地方编写相同的代码):

    服务器代码-不再有数据报,只使用来自套接字的输入/输出流,使用实用程序包装为读/写器

      public class TCPServer
      implements Runnable // in case you want to run the server on a separate thread
      {
        ServerSocket listenOnThis;
    
        public TCPServer(int port)
        throws IOException {
          this.listenOnThis=new ServerSocket(port);
        }
    
        @Override
        public void run() {
          int client=0;
          while(true) {
            try {
              Socket clientConn=this.listenOnThis.accept();
              RequestProcessing processor=new RequestProcessing(clientConn, client++);
              processor.start();
            } catch (IOException e) {
              break;
            }
    
          }
        }
    
        static public void main(String args[]) {
          // port to be provided as the first CLI option
          TCPServer server=new TCPServer(Integer.valueOf(args[0]));
          server.run(); // or spawn it on another thread
        }
      }
    
      class RequestProcessing extends Thread {
        Socket channel;
        int clientNo;
    
        public RequestProcessing(Socket s, int i) {
          channel = s;
          clientNo = i;
        }
    
        public void run() {
          try {
            SocketRW utility=new SocketRW(this.channel);          
            while (true) { 
              String theString=utility.readLine().trim();
              System.out.println("Client " + clientNo 
                  + " sent: " + theString);
              if ("quit".equals(theString)) {
                System.out.println("Client " + clientNo 
                    + " disconnected");
                this.channel.close();
                break;
              }
              theString = theString.toUpperCase();
              utility.println(theString);
            }
          } catch (IOException e) {
            System.err.println(e);
          }
        }
      }
    
    客户端代码-不再使用数据报套接字,使用套接字的相同IO流

      class TCPClient
      implements Runnable // just in case you want to run multithreaded clients
      {
        Socket socket;
    
        public TCPClient(InetAddress serverAddr, int port)
         throws IOException {
          this.socket=new Socket(serverAddr, port);
        }
    
        public void run() {
          String theString="";
          InputStreamReader isr = new InputStreamReader(System.in);
          try {
            SocketRW utility=new SocketRW(this.socket);
            BufferedReader br = new BufferedReader(isr);
            do {
              System.out.print("Enter message: ");
              theString = br.readLine().trim();
              utility.println(theString);
              System.out.println("Sent to server server: " + theString);
    
              String received=utility.readLine();
              System.out.println("Server reply: "+received);
    
            } while (!"quit".equals(theString));
          }
          catch(IOException e) {
            e.printStackTrace();
          }
        }
    
        static public void main(String[] args) {
          int port=Integer.valueOf(args[0]); // will throw if its no OK.
    
          TCPClient client=new TCPClient(
              InetAddress.getByName("192.168.109.128"),
              port
          );
    
          client.run();
        }
      }
    

    TCP端口与UDP端口是分开的。他的问题在于,他一直试图在每个客户端连接上绑定到UDP端口7。您的代码没有意义。您根本不需要TCP部分,也不需要服务器上的多个UDP套接字。
      class TCPClient
      implements Runnable // just in case you want to run multithreaded clients
      {
        Socket socket;
    
        public TCPClient(InetAddress serverAddr, int port)
         throws IOException {
          this.socket=new Socket(serverAddr, port);
        }
    
        public void run() {
          String theString="";
          InputStreamReader isr = new InputStreamReader(System.in);
          try {
            SocketRW utility=new SocketRW(this.socket);
            BufferedReader br = new BufferedReader(isr);
            do {
              System.out.print("Enter message: ");
              theString = br.readLine().trim();
              utility.println(theString);
              System.out.println("Sent to server server: " + theString);
    
              String received=utility.readLine();
              System.out.println("Server reply: "+received);
    
            } while (!"quit".equals(theString));
          }
          catch(IOException e) {
            e.printStackTrace();
          }
        }
    
        static public void main(String[] args) {
          int port=Integer.valueOf(args[0]); // will throw if its no OK.
    
          TCPClient client=new TCPClient(
              InetAddress.getByName("192.168.109.128"),
              port
          );
    
          client.run();
        }
      }