【问题标题】:Which socket descriptor receives the data if multiple connections set on same socket?如果在同一个套接字上设置多个连接,哪个套接字描述符接收数据?
【发布时间】:2021-03-18 17:27:42
【问题描述】:

我有一个服务器程序。下面给出代码sn-p;

int sd = socket(AF_INET , SOCK_STREAM , 0);
....
//socket is set a a non blocking socket
....
bind(sd, (struct sockaddr *)&address, sizeof(address));
...
listen(sd, 3);
..
int i = 0;
while(TRUE) {
int new_sd[i] = accept(sd,sockadd,sockadd_len);
i++;
}

场景是 3 个客户端连接到此服务器/套接字。当这些客户端开始向该服务器发送数据时,哪个套接字描述符将在服务器中具有该 (new_sd[0],new_sd[1],new_sd[2])?数据将如何分布在不同的套接字描述符之间?

【问题讨论】:

  • 基于连接的客户端地址
  • accept() 返回的每个描述符都是一个不同的套接字连接。当客户端向您的服务器发送数据时,相应的套接字将处于可读状态。使用recv()read() 从相应的套接字描述符中读取该客户端的数据。使用select()(e)poll() 了解哪些套接字描述符处于可读状态。

标签: c sockets tcp udp


【解决方案1】:

accept() 返回的套接字描述符将包含与发起 accept() 接受的连接的客户端进行通信的值。

你有代码:

int i = 0;
while(TRUE) {
    int new_sd[i] = accept(sd, sockadd, sockadd_len);
    i++;
}

这是一场灾难。您创建一个零长度数组(这不是有效的标准 C,尽管 GCC 允许),然后尝试访问数组边界之外的元素(零长度数组中没有有效元素)。您的循环丢弃了数组,然后尝试写入现在大小为 1 的数组的边界之外(只有 new_sd[0] 有效,但您可以访问 new_sd[1])。理论上,每次迭代都会放弃旧数组,所有值都变得不确定。您需要预先分配一个足够大的数组来容纳接受的连接,或者使用动态内存分配(malloc() 等)在循环时创建一个。您通常不应该在每次迭代时简单地将一个元素添加到数组中。显然,缺少实际从接受的套接字描述符中读取的代码。您还需要清理数组以删除与客户端的通信已完成并且您已关闭套接字描述符的条目。

【讨论】:

    猜你喜欢
    • 2021-10-21
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多