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

Rom*_*man 10 sockets networking client-server

根据我的理解,serverSocket = new ServerSocket(portNumber)我们创建了一个可能"监听"指示端口的对象.通过clientSocket = serverSocket.accept()我们强制服务器套接字"监听"其端口并从任何尝试通过与服务器关联的端口连接到服务器的客户端"接受"连接.当我说"客户端尝试连接到服务器"时,我的意思是客户端程序执行"nameSocket = new Socket(serverIP,serverPort)".

如果客户端尝试连接到服务器,则服务器"接受"此客户端(即创建与此客户端关联的"客户端套接字").

如果新客户端尝试连接到服务器,则服务器会创建另一个客户端套接字(与新客户端关联).但是服务器如何知道它是一个"新"客户端还是已经有套接字的"旧"客户端?或者,换句话说,如何识别客户?通过他们的IP?通过他们的IP和端口?通过一些"签名"?

如果"旧"客户端再次尝试使用Socket(serverIP,serverIP)会发生什么?服务器会创建与此客户端关联的第二个套接字吗?

Jim*_*ood 23

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

您的客户端IP地址是10.0.0.2,客户端"连接"到10.0.0.1端口8000的服务器.在TCP连接中,您将提供要连接的服务器的端口.您的客户端实际上会获得自己的端口号,但您无法控制它,并且每个连接都会有所不同.客户端选择要连接的服务器端口,而不是它连接的客户端端口.

例如,在第一个连接上,您的客户端可能会获得客户端端口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进入.


Jac*_*ack 5

每个TCP连接都具有四元组的标识符(src端口,src地址,dest端口,dest地址).

每当您的服务器接受新客户端时,Socket都会创建一个新的,并且它与目前为止创建的每个其他套接字无关.不知不觉地以某种方式处理客户身份.

您不必将套接字视为与"客户端"关联,它们与ip和端口关联,但这两者之间没有直接关联.

如果同一客户端尝试通过创建一个新套接字来打开另一个套接字,则会有两个不相关的套接字(因为端口肯定会不同).这是因为客户端不能使用相同的端口来打开新连接,因此四元组将是不同的,相同的客户端IP,相同的服务器IP,相同的服务器端口但不同的客户端端口.

编辑你的问题:

  1. 客户端没有指定端口,因为它从底层操作系统中随机选择了免费端口(> 1024,如果我没有错)
  2. 一个连接不能使用同一端口一个客户打开,操作系统不会让你这样做(其实你不指定任何端口的话),在任何情况下,它会告诉你该端口已经绑定到一个套接字所以这个问题不可能发生.
  3. 每当服务器接收到一个新的连接请求,它被认为是新的,因为如果还ip是同一个端口将是肯定的(旧数据包重发或类似警告的情况下,我认为该请求将被丢弃)不同

顺便说所有这些情况都在清楚解释TCP RFC 这里.