代码之家  ›  专栏  ›  技术社区  ›  Roman

如何识别客户机(客户机套接字)?

  •  8
  • Roman  · 技术社区  · 15 年前

    据我所知 serverSocket = new ServerSocket(portNumber) 我们创建一个对象,它可能会“监听”指定的端口。被 clientSocket = serverSocket.accept() 我们强制服务器套接字“监听”其端口并“接受”来自任何试图通过与服务器关联的端口连接到服务器的客户端的连接。当我说“客户端试图连接到服务器”时,我的意思是客户端程序执行“namesocket=new socket(serverip,serverport)”。

    如果客户机试图连接到服务器,则服务器“接受”此客户机(即创建与此客户机关联的“客户机套接字”)。

    如果新客户机尝试连接到服务器,服务器将创建另一个客户机套接字(与新客户机关联)。但是服务器如何知道它是一个“新的”客户机还是一个“旧的”客户机,而这个客户机已经有了自己的套接字?或者,换句话说,如何识别客户?通过他们的知识产权?通过他们的IP和端口?通过一些“签名”?

    如果“旧”客户端再次尝试使用套接字(serverip、serverip),会发生什么情况?服务器是否将创建与此客户端关联的第二个套接字?

    5 回复  |  直到 15 年前
        1
  •  21
  •   Jim Flood    15 年前

    服务器监听地址和端口。例如,您的服务器的IP地址是10.0.0.1,它正在监听端口8000。

    您的客户机IP地址是10.0.0.2,客户机在10.0.0.1端口8000“连接”到服务器。在TCPConnect中,您提供了要连接到的服务器的端口。您的客户机实际上会得到自己的端口号,但是您不能控制这个端口号,并且每个连接上的端口号都是不同的。客户选择 服务器 它要连接的端口,而不是 客户机 它所连接的端口。

    例如,在第一个连接上,客户机可能会获得客户机端端口12345。它从10.0.0.2端口12345连接到服务器10.0.0.1端口8000。您的服务器可以通过调用连接端的getpeername来查看客户机连接的端口。

    当客户端再次连接时,端口号将不同,比如端口12377。服务器可以通过在第二个连接上调用getpeername看到这一点——它将在客户端看到不同的端口号。(getpeername还显示客户端的IP地址。)

    此外,每次在服务器上调用accept,都会得到一个新的套接字。您仍然有原来的套接字在监听,并且在每次接受时都会得到一个新的套接字。在接受的套接字上调用getpeername以查看连接来自哪个客户端端口。如果两个客户机连接到您的服务器,那么现在您有三个套接字——原始侦听套接字,以及这两个客户机的每个套接字。

    您可以同时将多个客户机连接到同一服务器端口8000。而且,许多客户机可以从同一个客户机端口(例如端口12345)进行连接,但只能从不同的IP地址进行连接。从同一个客户机IP地址(例如10.0.0.2)到服务器端口8000的每个客户机连接都将来自一个唯一的客户机端口,例如12345、12377等。您可以通过IP地址和端口的组合来区分客户机。

    同一个客户机也可以同时与服务器建立多个连接,例如,一个连接来自客户机端口12345,另一个连接来自12377。客户机是指原始IP地址,而不是特定的软件对象。您将看到两个活动连接具有相同的客户机IP地址。

    而且,最终随着时间的推移,客户机地址和客户机端口的组合可以重用。也就是说,最终,在10.0.0.2端口12345的第一个客户机断开连接很久之后,您可能会看到一个新客户机从10.0.0.2端口12345进入。

        2
  •  5
  •   Jack    15 年前

    每个TCP连接都有四个字符作为标识符 (SRC端口、SRC地址、目标端口、目标地址) .

    每当服务器接受新客户机时,新客户机 Socket 是被创建的,它与迄今为止创建的所有其他套接字都是独立的。客户身份的确定并不是以某种方式进行的。

    您不必认为套接字与“客户机”关联,它们与一个IP和一个端口关联,但这两者之间没有直接的关联。

    如果同一个客户机试图通过创建一个新的套接字来打开另一个套接字,那么您将拥有两个不相关的套接字(因为端口肯定是不同的)。这是因为客户端无法使用同一端口打开新连接,所以四个端口将不同,相同的客户端IP、相同的服务器IP、相同的服务器端口,但不同的客户端端口。

    编辑您的问题:

    1. 客户端不指定端口,因为它是从底层操作系统的可用端口中随机选择的(如果没有错,则为1024)
    2. 无法从使用同一端口的客户端打开连接,操作系统不会允许您这样做(实际上您根本不指定任何端口),而且在任何情况下,它都会告诉您端口已经绑定到套接字,因此不会发生此问题。
    3. 每当服务器收到一个新的连接请求时,它都被认为是新的,因为同样,如果IP是同一个端口,那么肯定是不同的(如果是旧的数据包重新发送或类似的警告,我认为该请求将被丢弃)。

    顺便说一下,所有这些情况在 TCP RFC here .

        3
  •  0
  •   Pindatjuh    15 年前

    根据定义,这不是一个与Java相关的问题,而是关于网络的一般性问题,因为套接字和SaveCox适用于任何联网的编程语言。

    套接字被绑定到本地端口。客户端将打开与服务器的连接(通过操作系统/驱动程序/适配器/硬件/行/…/行/硬件/适配器/驱动程序/服务器操作系统)。这个“连接”是由一个称为IP(Internet协议)的协议在您连接到Internet时完成的。当您使用“sockets”时,它将使用另一个协议,即TCP/IP协议。

    因特网协议将通过两个东西来识别网络上的节点:它们的IP地址和端口。TCP/IP协议将使用IP发送消息,并确保正确接收消息。

    现在,回答你的问题:这要看情况而定!这取决于您的驱动程序、适配器、硬件和线路。当您连接到本地主机时,您得到的将不会超过适配器。硬件不是必需的,因为实际上没有数据通过线路发送。(尽管在使用适配器之前通常需要硬件。)

    根据定义,Internet协议将一个连接定义为一对节点(因此四件事:两个IP地址和两个端口)。此外,Internet协议定义一个节点一次只能使用一个端口来启动与另一个节点的连接(注意:这只适用于客户端,而不是服务器)。

    回答第二个问题:如果有两个插座:“新”和“旧”。因为,根据互联网协议,连接是一对节点,节点一次只能使用一个端口进行连接,“新”和“旧”的端口 必须 与众不同。因为这是不同的,“新”客户机可以区别于“旧”客户机,因为端口号是不同的。

        4
  •  0
  •   Manuel Darveau    15 年前

    我想这里的问题是,你为什么关心客户是新客户还是老客户。什么是新的和旧的? 例如,Web浏览器可以连接到Web服务器以请求网页。这将创建一个连接,因此 serverSocket.accept() 将返回新的 Socket . 然后通过Web浏览器关闭连接。

    几分钟后,最终用户点击网页中的链接,浏览器向服务器请求一个新页面。这将创建一个连接,因此 serversocket.accept()接受 将返回新的 插座 .

    现在,Web服务器不关心这是新客户机还是旧客户机。它只需要服务器请求的页面。如果服务器 注意,如果“客户机”在过去已经请求了一个页面,那么它应该使用套接字上使用的协议中的一些信息来完成请求。退房 http://en.wikipedia.org/wiki/OSI_model 在这种情况下, ServerSocket 插座 确认传输级别。“这个客户机是否已经在服务器上请求了一个页面”的问题应该由会话甚至应用程序层的信息来回答。

    在Web浏览器/服务器示例中,HTTP协议(即应用程序)在请求的参数中保存有关此浏览器是谁的信息(浏览器随每个请求传输cookie信息)。然后,HTTP服务器可以将cookie信息设置/读取为已知浏览器之前是否已连接,并最终为该浏览器维护服务器端会话。

    所以回到你的问题:你为什么关心它是新客户还是老客户?

        5
  •  0
  •   nos    15 年前

    插座通过以下方式识别:

    (本地IP、本地端口、远程IP, 远程端口、IP协议(udp/tcp/sctp/etc)

    这就是操作系统用来将数据包/数据映射到程序的正确句柄/文件描述符的信息。对于某些类型的套接字(例如非连接的UDP套接字),远程端口/远程IP可能是通配符。