所以我一直在关注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;
}
答案 0 :(得分:2)
正如上面评论中所提到的,您的终端“冻结”是由于您的呼叫在recv
上阻止。除非聊天室的其他成员发送更多信息,否则您的程序将只是坐在那里等待。您提到的指南是网络编程的一个很好的参考。返回并再次阅读第7.1节和第7.2节中的阻塞,特别是他在cheezy-chat-room示例中使用select()。它们使示例能够在不被卡住的情况下工作。
如果您不熟悉select()
,pselect()
和poll()
,请不要感到沮丧,它们是C中最重要但最具挑战性的方面之一与交朋友。花一点时间来阅读指南的7.1和7.2部分,花点时间了解select(),这将解决您的问题。 select()
,pselect()
和poll()
不限于网络的有用性,它们在程序IO的所有方面都很重要。