所以我一直在遵循Beej的指南,尝试学习一些基本的网络-http://beej.us/guide/bgnet/
所以我决定用一些为一些实践而编写的代码——所以我试图建立一个简单的终端聊天室,在那里输入IP地址,允许用户进行连接——我遇到的麻烦是,在我编辑的这个“服务器”文件上,当它发送信息时,它工作得很好,但是recv函数调用由于某种原因冻结了终端,我不确定为什么。我假设当accept工作正常时,新的套接字可以用来发送和接收来自,因为它代表客户机的套接字……这就是我有点卡住的地方。
另外,我想知道我应该学习哪些其他的图书馆来获得更实际的网络经验。我觉得这是一个很好的方法,让我的脚沾湿真正的低层次的东西(我喜欢它,因为它相当深),但我并不真的认为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;
}
最佳答案
如上所述,您的终端“冻结”是由于您在recv
上的呼叫阻塞所致。除非聊天室的另一个成员发送额外的信息,否则您的程序只需坐在那里永远等待。你提到的指南对网络编程是一个很好的参考。回到前面,再次阅读第7.1节和第7.2节关于阻塞的内容,特别是他在cheezy聊天室示例中使用select()的内容。它们使这个例子能够在不被卡住的情况下发挥作用。
如果你不熟悉select()
、pselect()
和poll()
,不要灰心,它们是C中最重要但最具挑战性的一部分,可以用来交朋友。花点时间回顾一下指南的第7.1节和第7.2节,花点时间理解select(),这将解决您的问题。select()
、pselect()
和poll()
不仅对网络有用,它们在程序IO的所有方面都很重要。
关于c - C套接字编程中的Recv与发送卡住在一起吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23840966/