【问题标题】:Multiplexing stdin and socket in client C在客户端 C 中复用标准输入和套接字
【发布时间】:2012-12-14 12:01:25
【问题描述】:

我编写了一个简单的 TCP 服务器来为许多客户端提供服务(它与 telnet 配合得很好)。但是,我还想编写自己的简单 TCP 客户端,带有多路复用套接字和标准输入。与我照常写的服务器连接,连接代码没问题。

我遇到了多路复用套接字和标准输入的问题。我的代码是最大的问题:

    void multiplexClient(FILE *fp, int sockfd, char inbuffer[], char outbuffer[])
    {
        int maxfd;
        fd_set rset;

        FD_ZERO(&rset);
        for(;;)
        {
            FD_SET(fileno(fp), &rset);
            FD_SET(sockfd, &rset);
            maxfd = std::max(fileno(fp), sockfd) + 1;

            int res = select(maxfd, &rset, NULL, NULL, NULL);

            if(res < 0)
            {
                printf("'select error\n");
            }

            if(FD_ISSET(sockfd, &rset))
            {
                if(read(sockfd, inbuffer, sizeof(inbuffer)) == 0)
                   printf("read error\n");
                printf("Received: %s\n", inbuffer);
                fflush(stdout);
                 memset(inbuffer, 0, sizeof(inbuffer));
            }

            else if(FD_ISSET(fileno(fp), &rset))
            {
                fprintf(stdout, "\n> ");
                if(fgets(outbuffer, sizeof(outbuffer), fp) == NULL)
                    return;
                write(sockfd, outbuffer, strlen(outbuffer));
                printf("Send: %s\n", outbuffer);
                fflush(stdout);
                 memset(outbuffer, 0, sizeof(outbuffer));
            }
        }
    }

// int main
// sockfd = socket...
// connect

while(1)
{
 multiplexClient(stdin, socket_fd, inbuffer, outbuffer);
}

// ...
    return 0;
}

我的第一个客户:

$ ./client localhost 9034
hello, other client!

> Send: hel
Received: hel
Received: lo! ��~�~���~�
Received: :)

Received: wha

我的第二个客户:

$ ./client localhost 9034
hello! :)

> Send: hel
whats is wrong with this chat?!

> Send: lo!

> Send:  :)

> Send: 


> Send: wha

如何解决这个问题?

【问题讨论】:

    标签: c sockets unix client-server multiplexing


    【解决方案1】:

    你的问题在这里(稍微解释一下):

    read(sockfd, inbuffer, sizeof(inbuffer));
    printf("Received: %s\n", inbuffer);
    

    read 调用返回写入的字节数(您忽略它),并且缓冲区不是 C 字符串(即,它不是以空值结尾的)。

    应该拥有的东西大致如下:

    quant = read (sockfd, inbuffer, sizeof(inbuffer));
    printf ("Received: %*.*s\n", quant, quant, inbuffer);
    

    【讨论】:

      【解决方案2】:

      在将文件选择器重新添加到集合之前,您缺少 FD_ZERO()

      另外,这是 C++,因为它使用 std::max()

      【讨论】:

      • 已添加,请参阅我的新帖子 - 它也没有帮助
      猜你喜欢
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-18
      • 2020-07-22
      相关资源
      最近更新 更多