sockets - 在不同程序中运行时选择始终返回 0

标签 sockets

我面临一个奇怪的问题,也许它很简单,但我缺乏太多的套接字知识也无济于事。

我创建了一个套接字程序,它在单独的程序中运行时完美运行,即在 main 中作为独立的 exe 单独运行。正如您在代码中看到的,在这个单独的程序中运行时,返回的套接字 fd 始终为 3。

当我复制同一段代码并将其集成到另一个打开了它自己的 fd 的服务器程序时,无论如何选择总是返回 0。在这种情况下,我的程序创建的 fd 始终为 6。

请参阅下面的程序。这段代码没有问题,只是在另一个服务器中运行时,select总是返回0。

当程序中已经存在一个 UDP 套接字 fd 时,我可以创建一个新的 UDP 套接字 fd。
当我的套接字 fd 与程序中已经打开的套接字不同时,为什么会发生这种情况。

为什么会发生这种情况,任何人都可以指导我该怎么做,或者任何指示都会有所帮助。

#define MY_TIMEOUT_S    5   
    int mySock;
    if ((mySock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("Cannot create UDP socket");
        return -1;
    }

    struct sockaddr_in myAddr;
    myAddr.sin_family       = AF_INET;
    myAddr.sin_port         = 0;
    myAddr.sin_addr.s_addr  = INADDR_ANY;
    memset(&(myAddr.sin_zero), '\0', 8);
    if (bind(mySock, (struct sockaddr*)&myAddr, 
            sizeof(struct sockaddr)) == -1) {
        perror("Cannot bind UDP socket to desired port");
        close(mySock);
        return -1;
    }

    // here send to remote target host on udp socket and port 

    char buf[MAX_UDP_PACKET_SIZE];
    struct sockaddr_in theirAddr;
    int addrLen = sizeof(struct sockaddr);

    fd_set readSet, curReadSet;
    FD_ZERO(&readSet);
    FD_SET(mySock, &readSet);
    int maxFD = mySock;
    while (true) {
        struct timeval timeOutTV = {MY_TIMEOUT_S, 0};

        memcpy(&curReadSet, &readSet, sizeof(fd_set));

        int selectRet = select(maxFD+1, &curReadSet, NULL, NULL, &timeOutTV);
        cout<<"select value =" <<selectRet<<endl;

        if (selectRet == -1) {
            if (errno == EINTR) {
                continue; // Interrupted by signal, retry
            }
            close(mySock);
            return -1;

        } else if (selectRet == 0) {
            close(mySock);
            return -1;
        }
        if (FD_ISSET(mySock, &curReadSet)) {
            int numBytes = recvfrom(mySock, buf, MAX_UDP_PACKET_SIZE, 0,
                    (struct sockaddr*)&theirAddr, (socklen_t*)&addrLen);
            if (numBytes == -1) {
                close(mySock);
            }   

        }
    }

从 lsof 输出添加一些细节

1)这是我必须发送数据的目标
须藤 lsof -a -p 16061

目标 16061 根 3r FIFO 0,8 0t0 153467 管道
目标 16061 根 4u IPv4 153470 0t0 UDP *:3290
目标 16061 root 5u sock 0,6 0t0 153471 无法识别协议(protocol)
目标 16061 根 6u IPv4 153472 0t0 TCP *:3290 (LISTEN)
目标 16061 根 7u 原始 0t0 153473 00000000:0001->00000000:0000 st=07

2)这是我在单独的exe中运行时的上述代码,其中只有这是在main中运行的代码
因为 FD=3 工作正常

须藤 lsof -a -p 16112

myProg 16112 根 0u CHR 136,4 0t0 7/dev/pts/4
myProg 16112 根 1u CHR 136,4 0t0 7/dev/pts/4
myProg 16112 根 2u CHR 136,4 0t0 7/dev/pts/4
myProg 16112 根 3u IPv4 153564 0t0 UDP *:60503

3)这是我在其中集成了上面相同的代码的 Web 服务器,它独立工作,但现在不是

这是我的网络服务器运行的输出

webServ 18431 根 3u unix 0xc09f9b00 0t0 157975 套接字
webServ 18431 根 4u IPv4 157976 0t0 UDP *:8080
webServ 18431 根 5u IPv4 157977 0t0 TCP *:8080 (LISTEN)

现在我发送请求并在服务器端执行我的新集成代码,我放置了一个无限循环并且没有关闭套接字只是为了显示 lsof 输出

4)我整合后的输出

webServ 18449 根 3u unix 0xc09f9b00 0t0 157975 套接字
webServ 18449 根 4u IPv4 157976 0t0 UDP *:8080
webServ 18449 根 5u IPv4 157977 0t0 TCP *:8080 (LISTEN)
webServ 18449 根 6u IPv4 158389 0t0 UDP *:48057

唯一的区别是当集成到服务器时,socket FD 是不同的,这是唯一的区别。

希望这有助于回答我的问题。

我不确定为什么会这样。请帮忙

最佳答案

做到这一点:

int maxFD = mySock + 1;

man page for select(2)说:

int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout);

nfds is the highest-numbered file descriptor in any of the three sets, plus 1.

关于sockets - 在不同程序中运行时选择始终返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13507473/

相关文章:

c++winsock2,如何判断连接何时关闭

java - 在java中杀死线程

linux - UDP套接字状态列表?

java - DatagramSocket如何每次都收包而不卡住

c++ - 在接收问题上阻塞套接字超时

c - ICMP header 和 IP header 校验和计算

c - 如何获取 Linux 中给定进程的 TCP 套接字的文件描述符?

c - C 的非 POSIX 套接字

sockets - 如何绑定(bind)到正确的地址和端口以进行 UDP 通信?

java - Java socket编程中如何实现客户端到服务器的持续交互