如何识别客户端(客户端套接字)?
根据我的理解,通过 serverSocket = new ServerSocket(portNumber)
我们创建了一个可能可以“侦听”指定端口的对象。通过 clientSocket = serverSocket.accept() ,我们强制服务器套接字“侦听”其端口并“接受”来自任何尝试通过与服务器关联的端口连接到服务器的客户端的连接。服务器。当我说“客户端尝试连接到服务器”时,我的意思是客户端程序执行“nameSocket = new Socket(serverIP,serverPort)”。
如果客户端尝试连接到服务器,则服务器“接受”该客户端(即创建与该客户端关联的“客户端套接字”)。
如果新客户端尝试连接到服务器,服务器将创建另一个客户端套接字(与新客户端关联)。但是服务器如何知道它是“新”客户端还是已经拥有其套接字的“旧”客户端呢?或者,换句话说,如何识别客户?通过他们的IP?通过他们的 IP 和端口?通过一些“签名”?
如果“旧”客户端尝试再次使用 Socket(serverIP,serverIP) 会发生什么?服务器会创建与该客户端关联的第二个套接字吗?
To my understanding by serverSocket = new ServerSocket(portNumber)
we create an object which potentially can "listen" to the indicated port. By clientSocket = serverSocket.accept()
we force the server socket to "listen" to its port and to "accept" a connection from any client which tries to connect to the server through the port associated with the server. When I say "client tries to connect to the server" I mean that client program executes "nameSocket = new Socket(serverIP,serverPort)".
If client is trying to connect to the server, the server "accepts" this client (i.e. creates a "client socket" associated with this client).
If a new client tries to connect to the server, the server creates another client socket (associated with the new client). But how the server knows if it is a "new" client or an "old" one which has already its socket? Or, in other words, how the clients are identified? By their IP? By their IP and port? By some "signatures"?
What happens if an "old" client tries to use Socket(serverIP,serverIP) again? Will server create the second socket associated with this client?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
服务器侦听地址和端口。例如,您的服务器的 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 进入。
The server listens on an address and port. For example, your server's IP address is 10.0.0.1, and it is listening on port 8000.
Your client IP address is 10.0.0.2, and the client "connects" to the server at 10.0.0.1 port 8000. In the TCP connect, you are giving the port of the server that you want to connect to. Your client will actually get its own port number, but you don't control this, and it will be different on each connection. The client chooses the server port that it wants to connect to and not the client port that it is connecting from.
For example, on the first connection, your client may get client-side port 12345. It is connecting from 10.0.0.2 port 12345 to the server 10.0.0.1 port 8000. Your server can see what port the client is connecting from by calling getpeername on its side of the connection.
When the client connects a second time, the port number is going to be different, say port 12377. The server can see this by calling getpeername on the second connection -- it will see a different port number on the client side. (getpeername also shows the client's IP address.)
Also, each time you call accept on the server, you are getting a new socket. You still have the original socket listening, and on each accept you get a new socket. Call getpeername on the accepted socket to see which client port the connection is coming from. If two clients connect to your server, you now have three sockets -- the original listening socket, and the sockets of each of the two clients.
You can have many clients connected to the same server port 8000 at the same time. And, many clients can be connected from the same client port (e.g. port 12345), only not from the same IP address. From the same client IP address, e.g. 10.0.0.2, each client connection to the server port 8000 will be from a unique client port, e.g. 12345, 12377, etc. You can tell the clients apart by their combination of IP address and port.
The same client can also have multiple connections to the server at the same time, e.g. one connection from client port 12345 and another from 12377 at the same time. By client I mean the originating IP address, and not a particular software object. You'll just see two active connections having the same client IP address.
Also, eventually over time, the combination of client-address and client-port can be reused. That is, eventually, you may see a new client come in from 10.0.0.2 port 12345, long after the first client at 10.0.0.2 port 12345 has disconnected.
每个 TCP 连接都有四元组(源端口、源地址、目标端口、目标地址)作为标识符。
每当您的服务器接受新客户端时,就会创建一个新的
Socket
,并且它独立于迄今为止创建的所有其他套接字。客户端的标识不会以某种方式隐式处理。您不必将套接字视为与“客户端”相关联,它们与 IP 和端口相关联,但两者之间没有直接关联。
如果同一个客户端尝试通过创建一个新套接字来打开另一个套接字,您将拥有两个不相关的套接字(因为端口肯定会不同)。这是因为客户端无法使用相同的端口打开新连接,因此四元组将不同,相同的客户端IP,相同的服务器IP,相同的服务器端口但不同的客户端端口。
编辑您的问题:
每当服务器收到新的连接请求时,它就被认为是新的,因为如果 ip 是相同的端口,肯定会有所不同 TCP RFC此处清楚地解释了这些情况。
Every TCP connection has as identifier the quadruple (src port, src address, dest port, dest address).
Whenever your server accepts a new client, a new
Socket
is created and it's indipendent from every other socket created so far. The identification of clients is not implictly handled somehow..You don't have to think sockets as associated to "clients", they are associated with an ip and a port, but there is not direct correlation between these two.
If the same client tries to open another socket by creating a new one you'll have two unrelated sockets (because ports will be different for sure). This because the client cannot use the same port to open the new connection so the quadruple will be different, same client ip, same server ip, same server port but different client port.
EDIT for your questions:
By the way all these situations are clearly explained in TCP RFC here.
我认为这里的问题是你为什么关心客户是新客户还是老客户。什么是新的和旧的?
例如,网络浏览器可以连接到网络服务器以请求网页。这将创建一个连接,因此
serverSocket.accept()
将返回一个新的Socket
。然后网络浏览器将关闭连接。几分钟后,最终用户单击网页中的链接,浏览器向服务器请求新页面。这将创建一个连接,因此
serverSocket.accept()
将返回一个新的Socket
。现在,Web 服务器不关心这是新客户端还是旧客户端。它只需要服务器请求的页面。如果服务器确实关心“客户端”过去是否已经请求过页面,则它应该使用套接字上使用的协议中的一些信息来这样做。查看http://en.wikipedia.org/wiki/OSI_model
在本例中,
ServerSocket
和Socket
在传输级别上进行确认。 “这个客户端是否已经请求服务器上的页面”这个问题应该通过会话甚至应用层的信息来回答。在 Web 浏览器/服务器示例中,http 协议(它是一个应用程序)在请求的参数中保存有关此浏览器是谁的信息(浏览器在每次请求时都会传输 cookie 信息)。然后,http 服务器可以设置/读取 cookie 信息,以了解浏览器之前是否连接过,并最终维护该浏览器的服务器端会话。
回到你的问题:为什么你关心它是新客户还是老客户?
I think the question here is why do you care if the client is new or old. What is new and old?
For example, a web browser could connect to a web server to request a web page. This will create a connection so
serverSocket.accept()
will return a newSocket
. Then the connection is closed by the web browser.Afer a couple of minutes, the end used click on a link in the web page and the browser request a new page to the server. This will create a connection so
serverSocket.accept()
will return a newSocket
.Now, the web server do not care if this is a new or old client. It just need to server the requested page. If the server do care if the "client" already requested a page in the past, it should do so using some information in the protocol used on the socket. Check out http://en.wikipedia.org/wiki/OSI_model
In this case, the
ServerSocket
andSocket
ack on the transport level. The question "does this client already requested a page on the server" should be answered by information on the session or even application layer.In the web browser/server example, the http protocol (which is an application) protocol hold information about who is this browser in the parameters of the request (the browser transmit cookie informations with every request). The http server can then set/read cookie information to known if the browser connected before and eventually maintain a server side session for that browser.
So back to your question: why do you care if it's a new or old client?
套接字通过以下方式标识:
这是操作系统用来将数据包/数据映射到程序的正确句柄/文件描述符的信息。对于某些类型的套接字(例如未连接的 UDP 套接字),远程端口/远程 IP 可能是通配符。
A socket is identified by:
And that's the information the OS uses to map the packets/data to the right handle/file descriptor of your program. For some kinds of sockets,(e.g. an non-connected UDP socket)the remote port/remote IP might be wildcards.
根据定义,这不是一个与 Java 相关的问题,而是关于一般网络的问题,因为 Sockets 和 SeverSockets 适用于任何支持网络的编程语言。
套接字绑定到本地端口。客户端将打开与服务器的连接(通过操作系统/驱动程序/适配器/硬件/线路/.../线路/硬件/适配器/驱动程序/服务器操作系统)。当您连接到互联网时,这种“连接”是通过称为 IP(互联网协议)的协议来完成的。当您使用“Sockets”时,它将使用另一个协议,即 TCP/IP 协议。
互联网协议将通过两件事来识别网络上的节点:IP 地址和端口。 TCP/IP 协议将使用 IP 发送消息,并确保正确接收消息。
现在;回答你的问题:这要看情况!这取决于您的驱动程序、适配器、硬件和线路。当您连接到本地主机时,您不会比适配器更进一步。硬件不是必需的,因为实际上没有数据通过线路发送。 (尽管在拥有适配器之前通常需要硬件。)
根据定义,互联网协议将连接定义为一对节点(因此有四件事:两个 IP 地址和两个端口)。另外,互联网协议定义一个节点一次只能使用一个端口来发起与另一个节点的连接(注意:这仅适用于客户端,不适用于服务器)。
回答你的第二个问题:是否有两个套接字:“新”和“旧”。由于根据互联网协议,连接是一对节点,并且节点一次只能使用一个端口进行连接,因此“新”和“旧”端口必须不同。并且因为这是不同的,所以可以将“新”客户端与“旧”客户端区分开来,因为端口号不同。
By definition, this is not a Java related question, but about networking in general, since Sockets and SeverSockets apply to any networking-enabled programming language.
A Socket is bounded to a local-port. The client will open a connection to the server (by the Operating System/drivers/adapters/hardware/line/.../line/hardware/adapters/drivers/Server OS). This "connection" is done by a protocol, called the IP (Internet Protocol) when you are connected to the Internet. When you use "Sockets", it will use another protocol, which is the TCP/IP-protocol.
The Internet Protocol will identify nodes on a network by two things: their IP-address and their port. The TCP/IP-protocol will send messages using the IP, and making sure messages are correctly received.
Now; to answer your question: it all depends! It depends on your drivers, your adapters, your hardware, your line. When you connect to your localhost machine, you will not get further than the adapter. The hardware isn't necessairy, since no data is actually sent over the line. (Though often you need hardware before you can have an adapter.)
By definition, the Internet Protocol defines a connection as pair of nodes (thus four things: two IP-adresses and two ports). Also, the Internet Protocol defines that one node can only use one port at a time to initiate a connection with another node (note: this only applies for the client, not the server).
To answer your second question: if there are two Sockets: the "new" and the "old". Since, by the Internet Protocol, a connection is a pair of nodes, and nodes can only use one port at a time for a connection, the ports of "new" and "old" must be different. And because this is different, the "new" client can be discriminated from the "old", since the port-number is differently.