Java 线程服务器如何继续在post上侦听更多的传入连接?

Java 线程服务器如何继续在post上侦听更多的传入连接?,java,sockets,Java,Sockets,我正在学习Sun的Java教程。我正在上关于插座的课。对于简单线程服务器,有以下代码: import java.net.*; import java.io.*; public class KKMultiServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; boolean listening = true;

我正在学习Sun的Java教程。我正在上关于插座的课。对于简单线程服务器,有以下代码:

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

public class KKMultiServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        boolean listening = true;

        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(-1);
        }

        while (listening)
        new KKMultiServerThread(serverSocket.accept()).start();

        serverSocket.close();
    }   
}
据说服务器“继续侦听更多的传入连接”。我只是不明白这怎么可能;行
serverSocket.accept()。那么,服务器如何可能与客户机通信并侦听同一端口上的更多传入连接呢?据我所知,如果某个端口用于某个连接,它将被阻塞,无法用于更多的事情

那么我在这里犯了什么错误呢?

基于此

accept方法等待客户端启动并请求此服务器的主机和端口上的连接(在本例中,服务器正在端口4444上的假设机器taranis上运行)。当请求并成功建立连接时,accept方法返回一个新的套接字对象,该对象绑定到同一本地端口,其远程地址和远程端口设置为客户端的地址和远程端口。服务器可以通过此新套接字与客户端通信,并继续侦听原始ServerSocket上的客户端连接请求。此特定版本的程序不会这样做侦听更多客户端连接请求

下面的讨论可能会消除关于单端口如何处理多个客户端调用的混淆


简单地说,大多数Web服务器在端口8080上侦听,多个客户端将访问同一端口以访问您的网站。

在同一端口上获得多个连接是完全可能的,因为每个TCP连接都是一个(本地主机、本地端口、远程主机、远程端口)元组只要至少1是不同的连接是不同的并且不会干扰(除了带宽下降)


试图连接到服务器的客户端通常会从操作系统中分配一个当前未使用的端口。好的,套接字不是基于端口的一对一,它在(地址,端口)元组中是唯一的。连接(通信中涉及的一对本地和远程套接字)用于将传入数据从端口解复用到正确的套接字,允许在一个端口上使用多个套接字。换句话说,套接字与端口之间的关系是N对1的,监听套接字的工作原理类似于企业电话交换机上的接待员。每个人都拨打交换机号码,接待员通过让其他人在另一条线路上处理来电来回应交换机线路上的每个来电。尽管接待员一次只能接一个电话,但交换线仅被短暂地占用,因为它仅用于建立连接

[…]TCP使用包含本地和外部地址的所有四个值来解复用传入段:目标IP地址、目标端口号、源IP地址和源端口号。TCP无法仅通过查看目标端口来确定哪个进程获取传入段。此外,[给定端口号]处的[各种]端点中唯一一个将接收传入连接请求的是处于侦听状态的端点。(第55页,TCP-IP图解卷1,W.Richard Stevens)

上面引用的最后一句话是理解的关键


有趣的是,套接字并不是通过IP地址和端口的组合来识别的。这仅在上下文中是唯一的,上下文是特定连接或侦听状态。只有一个侦听器套接字可以绑定到特定的IP/端口组合。

简单明了的答案是端口被其他程序和进程阻塞。现在只有打开端口的程序才能监听它。但它可以在同一端口上侦听多个不同的客户端

当客户端连接时,它会创建一个唯一的套接字。套接字由侦听IP地址和端口(您打开的那个)以及主叫IP地址和端口组成。因为调用者的IP地址和端口总是唯一的,所以每个套接字对于您的侦听器都是唯一的和可识别的


即使我从同一台机器连接到您的程序两次,我的机器也会为每个连接选择一个新的随机源端口,从而确保每次都有一个唯一的套接字。

可能重复:如果我想为每个新客户端分配一个新端口?什么是正确的方法?嗯,有趣的问题。。。每个客户机要么必须知道端口,以便使用某种静态分配方案提前检查,要么从服务器获取端口。或者,我猜,做一个端口扫描打开的端口,这是混乱的。无论如何,使用从服务器获取端口的方案,我会让客户端连接到一个已知的端口;服务器打开一个未分配的端口并用新的连接信息进行响应,然后客户端在新端口上重新连接。在任何情况下,我都不知道(但这并不排除存在)有任何标准的方法来做到这一点——我相信这都是应用程序级的。这个答案在每一个细节上都是不正确的,因为它将套接字与连接混为一谈。有关说明,请参见