我对 Socket 和 ServerSocket 端口的用法感到困惑。 Oracle's java tutorial about sockets说以下内容:
What Is a Socket?
Normally, a server runs on a specific computer and has a socket that is bound to a specific port number. The server just waits, listening to the socket for a client to make a connection request. On the client-side: The client knows the hostname of the machine on which the server is running and the port number on which the server is listening. To make a connection request, the client tries to rendezvous with the server on the server's machine and port. The client also needs to identify itself to the server so it binds to a local port number that it will use during this connection. This is usually assigned by the system.
If everything goes well, the server accepts the connection. Upon acceptance, the server gets a new socket bound to the same local port and also has its remote endpoint set to the address and port of the client. It needs a new socket so that it can continue to listen to the original socket for connection requests while tending to the needs of the connected client.
On the client side, if the connection is accepted, a socket is successfully created and the client can use the socket to communicate with the server. The client and server can now communicate by writing to or reading from their sockets.
我尝试了以下代码进行测试。但它会引发异常。
try {
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept();
// This prints 8080
System.out.println("Local port of accepted socket : " + socket.getLocalPort());
// But this throws java.net.BindException: Address already in use: JVM_Bind
Socket myClientSocket = new Socket("www.google.com", 80, null, 8080);
} catch (Exception e) {
e.printStackTrace();
}
我的问题很明显。虽然从 serverSocket.accept()
返回的套接字可以使用相同的本地端口 (8080
) 为什么我创建的套接字不能使用它?
最佳答案
为简单起见,监听的 TCP 套接字已经显式绑定(bind)到端口,因此您不能将第二个 TCP 套接字显式绑定(bind)到同一端口(除非两个套接字也显式绑定(bind)到不同的 IP 地址,不包括INADDR_ANY)。
接受的套接字不经过显式的“绑定(bind)”过程。它们会自动获取其本地 IP 地址和端口,如果您在未绑定(bind)的情况下连接出站套接字,它们也会自动获取。
关于java - Java ServerSocket accept client后如何获取绑定(bind)到同一本地端口的新套接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40842049/