我正在实现一个简单的TCP回显服务器,它回写写入它的任何内容。当我第一次向它发送一些数据时,使用telnet连接到它,它被发送回(预期)但之后挂起我假设没有发回任何东西。
这是我的代码(man getaddrinfo
中的示例的一个小修改版本)。下面我recv()
和send()
的方式有什么问题吗?
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#define MAX_LISTEN_BACKLOG 1
#define BUFFER_SIZE 4096
int main(int argc, char* argv[]){
char buf[BUFFER_SIZE];
int sfd,n,s;
struct addrinfo hints;
struct addrinfo *result;
struct addrinfo *rp;
struct sockaddr_storage peer_addr;
socklen_t peer_addr_len;
ssize_t nread;
int addr_info_error;
memset(&hints,0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
s = getaddrinfo(NULL, argv[1], &hints, &result);
if (s != 0){
printf("got error getaddrinfo");
}
for( rp = result; rp !=NULL; rp = rp->ai_next){
sfd = socket(rp->ai_family,rp->ai_socktype,rp->ai_protocol);
if (sfd == -1) perror("could not create socket");
if (bind(sfd,rp->ai_addr,rp->ai_addrlen) == 0 ) break;
close(sfd);
}
if (rp == NULL){
perror("could not bind");
}
freeaddrinfo(result);
int nsfd;
listen(sfd,100);
for(;;){
peer_addr_len = sizeof(struct sockaddr_storage);
nsfd = accept(sfd,(struct sockaddr*) &peer_addr_len,&peer_addr_len);
nread = recv(nsfd,buf,BUFFER_SIZE,0);
if(nread == -1)
continue;
printf("got ...%d",nread); // this line never prints?????
char host[NI_MAXHOST], service[NI_MAXSERV];
s = getnameinfo((struct sockaddr*) &peer_addr,
peer_addr_len,host,NI_MAXHOST,
service,NI_MAXSERV,NI_NUMERICSERV);
if (s == 0) printf("recieved %s bytes from host:%s port:%s",nread,host,service);
else printf("got %d in s",s);
if(send(nsfd,buf,nread,0) != nread)
perror("error sending response");
}
return 0;
}
答案 0 :(得分:-2)
[本文适用于无法阅读代码的人]
accept()
成功后添加额外的循环。一旦连接终止,此循环结束。for(;;){
peer_addr_len = sizeof(struct sockaddr_storage);
nsfd = accept(sfd,(struct sockaddr*) &peer_addr_len,&peer_addr_len);
if (nsfd ==-1) {perror("error sending response"); break; }
for(;;) {
nread = recv(nsfd,buf,BUFFER_SIZE,0);
fprintf(stderr, "got ...%d",nread);
if(nread == -1){
if(errno==EAGAIN) continue;
else break;
}
if(nread == 0) break;
char host[NI_MAXHOST], service[NI_MAXSERV];
s = getnameinfo((struct sockaddr*) &peer_addr,
peer_addr_len,host,NI_MAXHOST,
service,NI_MAXSERV,NI_NUMERICSERV);
if (s == 0) fprintf(stderr
, "received %s bytes from host:%s port:%s\n"
, nread,host,service);
else fprintf(stderr, "got %d in s\n", s);
if(send(nsfd,buf,nread,0) != nread) {
perror("error sending response");
break;
}
}
close(nsfd);
}