有一个称为socket();
的系统调用,它在侦听服务器上创建一个套接字。
我想要了解的是服务器创建IP +端口组合。
让我们说telnet使用端口23。
现在,当客户端机器进行连接,然后服务器正在侦听的端口,那么端口23上没有的连接实际上它位于不同的端口上。我的困惑是
在服务器端也会发生同样的事情。
例如,我编写了一个服务器来监听端口23然后将在服务器端与不同客户端进行的连接如何区分,因为它们都将位于同一个端口上。那么如何在同一台服务器上建立这么多连接如果有人用的话
telnet(23)或ftp(21)或ssh(22)然后许多人仍然可以登录到服务器上的相同服务端口,即不同用户使用ssh的多个连接,而ssh只在端口22处进行侦听。所以套接字是做什么的,或者套接字是如何创建的?
更新
我得到了解释的内容。取决于客户端机器上的IP +端口组合,其中连接源自服务器端的其余部分可以处理,我认为这些信息可能由套接字文件描述符使用。我所看到的是connect()
系统调用,我们使用如下
connect(sockfd,(struct sockaddr *)&client_address,size_t);
我们在客户端传递struct sockaddr *
,它具有唯一的IP +端口组合我认为当服务器接受它时接着然后事情继续进行。
我想进一步了解的是服务器端的论点
accept(server_sockfd,(struct sockaddr *)&client_address,(size_t *)sizeof (struct sockaddr ));
是否使用connect()传递来自客户端的相同client_address 系统调用?如果是,则侦听许多客户端的同一服务器的socket_descriptors是不同的。我想知道的是,当它接受来自客户端的请求时,服务器端的数据结构是如何维护的。
答案 0 :(得分:3)
TCP连接由4个参数标识:
因此,即使两个连接共享相同的本地IP和端口,操作系统也可以区分它们,因为远程IP和/或端口将会不同。
答案 1 :(得分:3)
标识连接的唯一组合是:
在您的示例中,许多连接的目标地址和端口是相同的,但每个连接都来自源地址和端口的唯一组合。
以下是我通过FTP(端口21)从桌面连接到服务器的简短tcpdump
会话:
22:55:50.160704 IP 172.17.42.19.64619 > 172.17.42.1.21: S 2284409007:2284409007(0) win 8192 <mss 1460,nop,nop,sackOK>
22:55:50.160735 IP 172.17.42.1.21 > 172.17.42.19.64619: S 1222495721:1222495721(0) ack 2284409008 win 65535 <mss 1460,sackOK,eol>
22:55:50.160827 IP 172.17.42.19.64619 > 172.17.42.1.21: . ack 1 win 8192
22:55:50.162991 IP 172.17.42.1.21 > 172.17.42.19.64619: P 1:61(60) ack 1 win 65535
22:55:50.369860 IP 172.17.42.19.64619 > 172.17.42.1.21: . ack 61 win 8132
22:55:56.288779 IP 172.17.42.19.64620 > 172.17.42.1.21: S 3841819536:3841819536(0) win 8192 <mss 1460,nop,nop,sackOK>
22:55:56.288811 IP 172.17.42.1.21 > 172.17.42.19.64620: S 454286057:454286057(0) ack 3841819537 win 65535 <mss 1460,sackOK,eol>
22:55:56.288923 IP 172.17.42.19.64620 > 172.17.42.1.21: . ack 1 win 8192
22:55:56.290224 IP 172.17.42.1.21 > 172.17.42.19.64620: P 1:61(60) ack 1 win 65535
22:55:56.488239 IP 172.17.42.19.64620 > 172.17.42.1.21: . ack 61 win 8132
22:56:03.301421 IP 172.17.42.19.64619 > 172.17.42.1.21: P 1:12(11) ack 61 win 8132
22:56:03.306994 IP 172.17.42.1.21 > 172.17.42.19.64619: P 61:94(33) ack 12 win 65535
22:56:03.510663 IP 172.17.42.19.64619 > 172.17.42.1.21: . ack 94 win 8099
22:56:06.525348 IP 172.17.42.19.64620 > 172.17.42.1.21: P 1:12(11) ack 61 win 8132
22:56:06.526332 IP 172.17.42.1.21 > 172.17.42.19.64620: P 61:94(33) ack 12 win 65535
22:56:06.726857 IP 172.17.42.19.64620 > 172.17.42.1.21: . ack 94 win 8099
您可以看到初始连接为172.17.42.19.64619 <-> 172.17.42.1.21
。端口64619是Windows 7框在进行传出连接时选择作为源端口的内容。带有S
的两行是来回传递的SYN
数据包以建立连接。然后我开始下一个连接,Windows只使用下一个可用端口64620.连接172.17.42.19.64620 <-> 172.17.42.1.21
形成了我在顶部列出的项目的新唯一元组。只有客户端的端口不同,但这就足够了。到达端口21的每个数据包都可以通过源端口进行区分。到达客户端的服务器上来自端口21的每个数据包都可以通过目标端口进行区分。
答案 2 :(得分:-1)
我会从Qt给你伪代码来解释这个问题。所有TCP服务器都以相同的方式工作。
首先创建一个侦听TCP服务器套接字。当传入的连接请求到达时,操作系统会创建一个新的套接字(您的操作系统使用与侦听套接字不同的端口),并将此新套接字与远程客户端关联。 TCP服务器套接字继续接受新连接,并通过新创建的套接字恢复与远程对等方的通信。
tcpServer.listen(LocalHost, PORT);
connect(&tcpServer, SIGNAL(newConnection()),this, SLOT(NewConnection()));
//Callback that is called when server accepts a new connection
void NewConnection()
{
//Here you will have a new socket for communication with the client
//The tcpServer will continue listening to given port
QTcpSocket* connection = tcpServer.NextPendingConnection();
//Use your new connection to communicate with the remote client...
}
我希望这会有所帮助