用于等待在套接字中写入的select的奇怪行为

时间:2016-02-11 18:20:03

标签: c sockets

我只是想在连接套接字后等待,看看我是否可以写入它。 所以我创造了&连接我的套接字并使用"选择"做这项工作,除非......没有正确解决。

这是我的代码:

int SocketToBox(char boxIp[INET6_ADDRSTRLEN], int port)
{
    struct sockaddr_in boxAddress;
    int                sock      = -1;

    if ((sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) {
        printf("%s : socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0) : errno = '%s'.\n", __func__, strerror(errno));
        return (-1);
    }

    memset(&boxAddress, 0, sizeof(boxAddress));
    boxAddress.sin_family = AF_INET;
    boxAddress.sin_port = htons(port);
    if (inet_pton(AF_INET, boxIp, &boxAddress.sin_addr) != 1) {
        printf("%s : inet_pton(AF_INET, boxIp<'%s'>, &boxAddress.sin_addr) : errno = '%s'.\n", __func__, boxIp, strerror(errno));
        close(sock);
        return (-1);
    }

    if (connect(sock, (struct sockaddr *)&boxAddress, sizeof(boxAddress)) == -1) {
        if (errno != EINPROGRESS) {
            printf("%s : connect(sock<%d>, (struct sockaddr *)&boxAddress, sizeof(boxAddress)) : errno = '%s'.\n", __func__, sock, strerror(errno));
            close(sock);
            return (-1);
        }
    }
    return (sock);
}



int main(void)
{
    int    sock;
    fd_set writeFdSet;
    char   *message   = "Hello World !";

    if ((sock = SocketToBox("192.192.192.192", 2000)) == -1) {
        printf("%s : SocketToBox(\"192.192.192.192\", 2000) : callstack.\n", __func__);
        return (1);
    }

    FD_ZERO(&writeFdSet);
    FD_SET(sock, &writeFdSet);

    if (select(sock + 1, NULL, &writeFdSet, NULL, NULL) == -1) {
        printf("%s : select(sock<%d> + 1, NULL, &writeFdSet, NULL, NULL) : errno = '%s'.", __func__, sock, strerror(errno));
        return (1);
    }

    if (FD_ISSET(sock, &writeFdSet)) {
        printf("socket UP.\n");

        if (send(sock, message, strlen(message), MSG_DONTWAIT) == -1) {
            printf("%s : send(sock<%d>, message<'%s'>, strlen(message)<%zu>, MSG_DONTWAIT) : errno '%s'.\n", __func__, sock, message, strlen(message), strerror(errno));
            return (1);
        }
        printf("Message sended.\n");
    } else {
        printf("socket DOWN.\n");
    }

    FD_ZERO(&writeFdSet);
    if (sock == -1) {
        close(sock);
    }
    return (0);
}

我的输出:

socket UP.
main : send(sock<3>, message<'Hello World !'>, strlen(message)<13>, MSG_DONTWAIT) : errno 'Connection timed out'.

我错过了什么? 选择返回1,我也不明白!为什么1而不是0? 为什么我的套接字被标记为&#34;可写&#34;通过选择何时发送失败? 我可以向你保证,我不能ping 192.192.192.192。

2 个答案:

答案 0 :(得分:0)

来自the select manual page

  

成功时,select()pselect()返回三个返回的描述符集中包含的文件描述符数

这就是select函数为你返回1的原因:它返回时在集合中设置了一个描述符。

对于第二个问题,也可以从手册页中找到:

  

如果可以执行相应的I / O操作(例如,read(2)没有阻塞或足够小的write(2)),则认为文件描述符已准备好。

  将会看到writefds中的那些人,看看空间是否可用于写入(尽管大写可能仍会阻塞)

因此,所有select都会告诉您描述符内部缓冲区中是否有可用空间,它没有说明数据是否可以实际发送。

答案 1 :(得分:0)

因为写入未连接的套接字不会阻止 - 这是唯一的选择保证你。