与C网络编程中的套接字有关的问题

时间:2011-06-29 07:14:36

标签: c sockets network-programming

有一个称为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是不同的。我想知道的是,当它接受来自客户端的请求时,服务器端的数据结构是如何维护的。

3 个答案:

答案 0 :(得分:3)

TCP连接由4个参数标识:

  • 本地IP
  • 本地端口
  • 远程IP
  • 远程端口

因此,即使两个连接共享相同的本地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...

}

我希望这会有所帮助