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

标签 networking sockets client-server

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

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

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

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

最佳答案

服务器监听地址和端口。例如,您的服务器的 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 进入。

关于networking - 如何识别客户端(客户端套接字)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2439472/

相关文章:

c - 处理多个客户端时,pthread_join 无法 fork TCP 服务器

Java - 发送到 OutputStream 的两个字符串之间的差异

sockets - 在子网掩码和路由方面的主机设备通信

android - 更改网络时接收 NETWORK_STATE_CHANGED_ACTION 已连接

python - 通过代理隧道化 httplib

sockets - Haskell 中的非阻塞 UDP 接收

c++ - 我可以写一个封闭的 socket 并强行纠正断管的错误吗?

image - 无法加载 YouTube 缩略图的网络图像 Flutter Web

ubuntu - 从 Redis 检索大型数据集

c - C winapi中服务器的实现