c - 如何在同一套接字上循环发送 send() 和 receive() ?

标签 c loops sockets input

我正在尝试为 Freenode 创建 IRC 客户端

我的代码是这样的:

 while ((numbytes = recv(sockfd, buf, BUFFSIZE -1, 0)) != -1) {

        buf[numbytes] = '\0';
        printf("client: %s\n", buf);

        if (strstr(buf, "Nickname is already in use"))
            exit(EXIT_FAILURE);

        if (strstr(buf, "PING")) {
            num_bytes_sent = send(sockfd, "PONG", 5, 0);
            printf("%d PONG\n", num_bytes_sent);
        }        
}

我希望能够使用 send() 使用 scanf() 进行用户输入,但我无法在内部使用 scanf()循环,因为它会阻止套接字接收数据,直到 scanf() 接收到输入。有什么方法可以让循环继续接收数据而不停止等待用户输入吗?

最佳答案

您正在寻找的是 select系统调用。下面是它的使用示例(使用 writeread 而不是 sendrecv):

fd_set fds_receive;    // set of file descriptors
char buffer[BUFSIZE];

FD_ZERO(&fds_receive); // initialize the set

while (1) {

        FD_SET(socket_fd, fds_receive);  // monitor the socket
        FD_SET(STDIN_FD, fds_receive);   // monitor stdin

        /* the select system call will return when one of the file
        descriptors that it is monitoring is ready for an I/O operation */
        if (select(FD_SETSIZE, &fds_receive, NULL, NULL, NULL) < 0) {
            perror("select");
            exit(-1);
        }

        // if new data arrives from stdin
        if (FD_ISSET(STDIN_FD, &fds_receive)) {
            num_bytes = read(STDIN_FD, buffer, sizeof(buffer));

            if (num_bytes < 0) {          // error in the "read" system call
                perror("read");
                exit(-1);
            } else if (num_bytes == 0) {  // "Ctrl+D" pressed, stdin receives 0 bytes
                if (close(socket_fd) < 0) {
                    perror("close");
                    exit(-1);
                }

                exit(0);
            }

            // send data received in stdin to socket
            buffer[num_bytes] = '\0';
            if (write(socket_fd, buffer, strlen(buffer)+1) < 0) {
                perror("write");
                exit(-1);
            }

        } 

        // if new data arrives from the socket
        if (FD_ISSET(socket_fd, &fds_receive)) {
            num_bytes = read(socket_fd, buffer, sizeof(buffer));

            if (num_bytes < 0) {         // error in the "write" system call
                perror("read");
                exit(-1);
            } else if (num_bytes == 0) { // connection terminated, no problem
                close(socket_fd);
                exit(0);
            }

            // do stuff with data that arrived from the socket
        }
    }

select 系统调用允许您监视多个文件描述符。在这种情况下,如果您想同时监视 stdin 和套接字,则可以将它们放在一组文件描述符上。代码中的注释应该有助于理解它是如何工作的。干杯!

关于c - 如何在同一套接字上循环发送 send() 和 receive() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59459197/

相关文章:

c - 何时在扩展的 GCC 内联汇编中使用 earlyclobber 约束?

c - 在 C 中存储 char* 数组

php - mysql 内连接中的 while 循环

c++ - 程序在 accept() 之后终止启动线程

c - 如何操作数字的数字?

c - 如何检查 Windows 用户是否具有 C 中的管理员权限?

python - 如何比较字典中的键并查看一个键是否包含另一个键?

Python 循环遍历不同长度的嵌套系列

c - 用recv()确定数据包大小的最佳方法是什么?

php - 在 socket.io 中调用 laravel 事件