C语言编程中的Recv与send一起冻结?

时间:2014-05-24 03:14:30

标签: c sockets networking send recv

所以我一直在关注Beej的指南,尝试学习一些基本的网络 - http://beej.us/guide/bgnet/

所以我决定玩一些为某些练习而编写的代码 - 所以我试图创建一个简单的终端聊天室,输入IP地址允许用户连接 - 麻烦我&# 39; m就是这个"服务器"文件我已经编辑过,它在发送信息时效果很好,但是由于某些原因,recv函数调用会冻结终端,我不确定为什么。我假设当accept正常工作时,new_fd套接字可用于发送和接收,因为它代表客户端的套接字......这就是我陷入困境的地方。

另外,我想知道我应该学习哪些其他库来获得更实用的网络体验。我觉得这是一个很好的方式来让我的脚湿透了很低级别的东西(我喜欢它,因为它非常深)但是我并没有真正看到C网络库在比较中特别有效到那里的其他东西 -

int waiting = 1;
char input = ' ';
char message[100];
memset(&message, 0, sizeof message);

while(waiting) {  // main accept() loop
    sin_size = sizeof their_addr;
    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
    if (new_fd == -1) {
        perror("accept");
        continue;
    }

    inet_ntop(their_addr.ss_family,
        get_in_addr((struct sockaddr *)&their_addr),
        s, sizeof s);//converts an IP address we get signal from to readable string
    printf("%s wants to chat with you.\nAccept? Y/n\n", s);
    scanf("%c", &input);


    if (input == 'Y' || input == 'y') {

        int rv;

        /*if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("client: connect");
            continue;
        }*/

        waiting = 0;
    }
    else {
        printf("Waiting Mode\n");

    }
}

char buf[100];
char prev[100];
char nil[100];
memset(nil, 0, sizeof nil);
int numbytes;

while (1) {

        fgets(message, 100, stdin);


        if (send(new_fd, message, 100, 0) == -1) {
            perror("send");
        }


        if ((numbytes = recv(new_fd, buf, 100, 0)) == -1) {
            perror("recv");
            exit(1);
        }

        /*if (strcmp(prev, buf) == 0 || strcmp(nil, buf) == 0 ) {
            continue;
        }

        buf[numbytes] = '\0';
        printf("\n%s\n", buf);
        memmove(prev, buf, sizeof buf);*/


}

return 0;

}

1 个答案:

答案 0 :(得分:2)

正如上面评论中所提到的,您的终端“冻结”是由于您的呼叫在recv上阻止。除非聊天室的其他成员发送更多信息,否则您的程序将只是坐在那里等待。您提到的指南是网络编程的一个很好的参考。返回并再次阅读第7.1节和第7.2节中的阻塞,特别是他在cheezy-chat-room示例中使用select()。它们使示例能够在不被卡住的情况下工作。

如果您不熟悉select()pselect()poll(),请不要感到沮丧,它们是C中最重要但最具挑战性的方面之一与交朋友。花一点时间来阅读指南的7.1和7.2部分,花点时间了解select(),这将解决您的问题。 select()pselect()poll()不限于网络的有用性,它们在程序IO的所有方面都很重要。