【问题标题】:question related to sockets in network programming with C与 C 网络编程中的套接字有关的问题
【发布时间】:2011-06-30 19:20:45
【问题描述】:

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

【问题讨论】:

    标签: c sockets network-programming


    【解决方案1】:

    标识连接的唯一组合是:

    • 源地址和端口
    • 目标地址和端口

    在您的示例中,许多连接的目标地址和端口都相同,但每个连接都来自源地址和端口的唯一组合。

    这是我通过 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 &lt;-&gt; 172.17.42.1.21。端口 64619 是 Windows 7 框在建立传出连接时碰巧选择的源端口。带有S 的两行是来回建立连接的SYN 数据包。然后我开始下一个连接,Windows 只使用下一个可用端口 64620。连接172.17.42.19.64620 &lt;-&gt; 172.17.42.1.21 形成了我在顶部列出的项目的一个新的唯一元组。只有客户端的端口不同,但这已经足够了。每个到达服务器到端口 21 的数据包都可以通过源端口来区分。每个来自服务器上的21端口到达客户端的数据包都可以通过目的端口来区分。

    【讨论】:

    • 那么它是如何区分连接的呢?
    • @Registered:我添加了一个示例。如果这还不够,请尝试解释您的理解,以便我们知道您在想什么。
    • 非常感谢您的回答,我深入研究并更新了问题。
    【解决方案2】:

    TCP 连接由 4 个参数标识:

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

    因此,即使两个连接共享相同的本地 IP 和端口,操作系统也可以区分,因为远程 IP 和/或端口将不同。

    【讨论】:

      【解决方案3】:

      我会给你来自 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...
      
      }
      

      希望对你有帮助

      【讨论】:

      • 如果我写的有问题请解释!您至少应该表现出输入评论的礼貌!
      • 我没有对其他人的问题投反对票,我已经 +1 投票了。此外,我不是 Qt 人,所以不知道。
      • 它没有分配新的端口。接受的套接字使用与监听套接字相同的端口。
      猜你喜欢
      • 1970-01-01
      • 2011-03-06
      • 2021-04-02
      • 2022-10-06
      • 2013-03-18
      • 1970-01-01
      • 1970-01-01
      • 2021-02-06
      • 2016-03-30
      相关资源
      最近更新 更多