【问题标题】:C socket: recv and send simultaneouslyC套接字:同时接收和发送
【发布时间】:2016-07-28 00:11:37
【问题描述】:

我正在尝试使用单个服务器和多个客户端场景制作客户端服务器聊天应用程序。我的服务器正在工作,但我无法让客户端正常工作。我正在使用 select() 函数来选择我应该是 recv() 还是 send()。这是我的客户端实现代码。

main()
{
int sockfd;
struct sockaddr_in serv_addr;

int i, sent;
char buf[100];
char buff[100];

/*
Opening a socket 
Check whether opening is successful or not
*/
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
    printf("Unable to create socket\n");
}
printf("Socket created\n");


serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(6000);

/*
Establish a connection with the server process
*/
if((connect(sockfd, (struct socketaddr *)&serv_addr, sizeof(serv_addr)))<0){
    printf("Unable to connect to server\n");
    exit(0);
}

printf("Client connected\n");

while(1){

    for(i=0; i<100; i++){
        buf[i] = '\0';
        buff[i] = '\0';
    }

    fd_set rfd, wfd;
    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO( &rfd);
    FD_ZERO( &wfd);

    FD_SET( sockfd, &rfd);
    //FD_SET( sockfd, &wfd);
    FD_SET( 0, &wfd);

    if( (select( sockfd + 1, &rfd, &wfd, NULL, &tv) < 0)) {
        printf(" Select error \n");
        exit(0);
    }

    if( FD_ISSET( sockfd, &rfd)) { // we got data ... need to read it
        recv(sockfd, buff, 100, 0);
        printf("Received result from server = %s\n",buff);
    }

    if( FD_ISSET( 0, &wfd)) {
        fflush(stdin);
        printf(">");
        gets(buf);
        sent = send(sockfd, buf, strlen(buf) + 1, 0);
        printf("-------------Sent %d bytes to server--------------\n", sent);
    }
}
printf("----------------Closing client------------------ \n");
close(sockfd);
}

每个客户端都应该得到一个客户端发送到服务器的消息,就像聊天应用程序一样。

【问题讨论】:

  • 与您的问题无关,但您应该知道在输入流中调用fflush(如stdin)是未定义。如果您希望代码可移植,请不要这样做。您还应该永远使用gets,它很危险,甚至已从 C 标准中删除。我还建议您使用例如STDIN_FILENO 而不是 "magic number" 0
  • @Joachim 非常感谢!!我应该使用fgets 而不是gets 吗?
  • 是的,这是推荐的替代品。请注意,fgets 会将换行符添加到缓冲区中(如果合适的话),因此您必须检查并删除它(通过将其替换为字符串终止符)。
  • 我认为它必须停止在第三个 if 因为gets()而在while循环中阻塞......所以它不能像实时聊天应用程序那样读取,不是吗?

标签: c sockets select tcp network-programming


【解决方案1】:

问题在于您检查是否可以写入 到标准输入 文件描述符。这没有意义,你应该检查你是否可以从中读取

也就是说,你也应该将STDIN_FILENO添加到读集,而根本没有写集。

【讨论】:

    【解决方案2】:

    几天前我遇到了同样的问题,但在 c++ 中。使用这些链接解决了我的问题:

    可能你可以适应你的情况,这个socket server会根据你的需要进行广播。尝试编译它,你会看到它是如何工作的。

    如果您需要帮助,请随时提出。

    【讨论】:

    • 感谢您的回复! Joachim Pileborg 的回答解决了我的问题,但感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 2014-11-25
    • 2013-04-01
    • 2021-07-08
    • 2010-11-14
    • 2013-11-19
    • 2019-07-04
    • 2016-02-21
    • 2012-10-05
    相关资源
    最近更新 更多