【问题标题】:Implementing chat client following Beej's guide to network programming按照 Beej 的网络编程指南实现聊天客户端
【发布时间】:2015-03-13 15:45:37
【问题描述】:

我正在尝试通过关注Beej's guide 来学习网络编程。我已经编译了the server in section 7.2,使用的是select(),现在我正在尝试为该服务器编写一个客户端,这样我就可以在我的机器上打开两个终端并能够聊天。

我从client he gives as an example in section 6.2 开始,我可以看到如果我连接到localhost,服务器会接受连接,所以我从那里开始。

我所做的是在与服务器的连接被接受后立即编辑该部分(在freeaddrinfo(servinfo); // all done with this structure 之后),这是我添加的代码部分。

while (1) {

    FD_ZERO(&readfds);
    FD_ZERO(&writefds);

    FD_SET(STDIN, &readfds);
    FD_SET(sockfd, &writefds);

    fcntl(STDIN, F_SETFL, O_NONBLOCK);

    if (select(sockfd+1, &readfds, &writefds, NULL, NULL) < 0) {
        close(sockfd);
        perror("client: select");
        exit(1);
    }

    if (FD_ISSET(sockfd, &writefds)) { // got data from socket, write it to console
        numbytes = recv(sockfd, buf, MAXDATASIZE, 0);
        buf[numbytes] = '\0';
        printf("%s\n", buf);
    }

    if (FD_ISSET(STDIN, &readfds)) { // got data from stdin, write it to socket
        fgets(buf, MAXDATASIZE, STDIN);
        send(sockfd, buf, strlen(buf), 0);
    }
}

在尝试运行此代码时,我注意到recv() 永远不会返回。我知道这段代码远非完美,但这是我第一次使用套接字,所以我很想得到一些关于我在这里做错了什么的指导。

【问题讨论】:

    标签: c sockets network-programming posix


    【解决方案1】:

    recv(2) 是一个读操作,所以sockfd 应该进入readfds 而不是writefds

    (顺便说一句,STDIN 来自哪里?在 POSIX 系统上,您可以使用 STDIN_FILENO。)

    您已经说过这是简单的测试代码(在实践中可能会按预期工作),但以防万一您不知道:recv() 可能会任意拆分数据。作为一个极端的例子,它可以一次返回一个字节。

    【讨论】:

    • @Quaker:这是因为STDIN 是一个整数,而不是FILE*。 (它是 0,这意味着您正在传递一个空指针。:) 改用 stdin(小写字母)。您也可以直接使用read(2),或者只是为send() 硬编码一些测试字符串。
    • writefds 什么都得不到,readfds 两者都有。您正在等待从stdin 或服务器读取数据。
    • writefds 将等待写入成为可能。例如,如果一个进程正在写入另一个进程,而另一个进程没有读取数据,那么缓冲区最终会填满,因此写入会阻塞。 writefds 可用于在没有阻塞的情况下可以写入时获得通知(例如,一旦其他进程读取了一些数据)。
    • 或者send() 会在你使用非阻塞套接字时返回错误(这将是浪费精力),这在writefds 中很常见。不过,在开始时这并不是非常重要的事情。 :)
    • @Quaker:如果它想一次返回一个字节。也许这是有问题的英语(不是母语人士:),但在我耳边听起来不错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 2015-07-03
    • 1970-01-01
    相关资源
    最近更新 更多