我是一个套接字/网络代码新手,所以这可能是一个愚蠢的问题。
我正在运营多个本地"客户"和本地"服务器"使用AF_INET协议。
但是,当我尝试将所有客户端连接到服务器时,它们似乎连接在同一个套接字上,使得从单个无意义的读取。
以下代码演示了该问题,与任何服务器代码无关。
#include <iostream>
#include <sys/socket.h>
int main(int argc, char* argv[])
{
int sockfd; // socket file descriptor
sockfd = socket(AF_INET, SOCK_STREAM, 0);
std::cout<<"socket is "<<sockfd<<std::endl;
/* perform various i/o tasks */
return 0;
}
无论有多少进程正在运行,此处的套接字始终为3
。
这是预期的吗?如果是这样,那么可能是最好的方式来解决这类问题,因为我希望使用互联网协议在本地网络或在线上提供相同的功能。
答案 0 :(得分:3)
是的,这是预期的; file descriptors - 至少符合POSIX标准 - 由您的操作系统按流程执行:
通常,文件描述符是包含打开文件详细信息的内核驻留阵列数据结构中的条目的索引。在POSIX中,此数据结构称为文件描述符表,每个进程都有自己的文件描述符表。该进程通过系统调用将文件描述符传递给内核,内核将代表进程访问该文件。进程本身无法直接读取或写入文件描述符表。
在Linux上,可以在/ proc / PID / fd /路径下访问进程中打开的文件描述符集,其中PID是进程标识符。
在类Unix系统中,文件描述符可以引用文件系统中指定的任何Unix文件类型。除常规文件外,还包括目录,块和字符设备(也称为“特殊文件”),Unix域套接字和命名管道。文件描述符还可以引用文件系统中通常不存在的其他对象,例如匿名管道和网络套接字。
因此,在您的情况下,默认情况下已经分配了以下内容:
0
stdin 1
stdout 2
stderr 因此,您首先要求自己成为3
。
您无需担心这一点。进程1100上的FD 3与进程1101上的FD 3完全不同。这不会对您的代码或客户端/服务器系统造成问题。您可能刚刚进行了测试以找到答案。
答案 1 :(得分:1)
socket
返回的数字不是套接字号,它只是OS和/或语言运行时维护的表的不透明索引。每个进程都有自己的表,因此复制这些数字是正常的,不用担心。
您可以使用getsockname
获取有关套接字本身的扩展信息,例如端口号。