旅游项目网站开发,模仿网站属于侵权吗,居然之家装修公司怎么样,wordpress如何设计主页转自#xff1a;http://blog.csdn.net/itcastcpp/article/details/39047265 前面几篇中实现的client每次运行只能从命令行读取一个字符串发给服务器#xff0c;再从服务器收回来#xff0c;现在我们把它改成交互式的#xff0c;不断从终端接受用户输入并和server交互。 [cp… 转自http://blog.csdn.net/itcastcpp/article/details/39047265 前面几篇中实现的client每次运行只能从命令行读取一个字符串发给服务器再从服务器收回来现在我们把它改成交互式的不断从终端接受用户输入并和server交互。 [cpp] view plain copy /* client.c */ #include stdio.h #include string.h #include unistd.h #include netinet/in.h #include wrap.h #define MAXLINE 80 #define SERV_PORT 8000 int main(int argc, char *argv[]) { structsockaddr_in servaddr; charbuf[MAXLINE]; intsockfd, n; sockfd Socket(AF_INET, SOCK_STREAM, 0); bzero(servaddr,sizeof(servaddr)); servaddr.sin_family AF_INET; inet_pton(AF_INET,127.0.0.1, servaddr.sin_addr); servaddr.sin_port htons(SERV_PORT); Connect(sockfd,(struct sockaddr *)servaddr, sizeof(servaddr)); while(fgets(buf, MAXLINE, stdin) ! NULL) { Write(sockfd,buf, strlen(buf)); n Read(sockfd, buf, MAXLINE); if(n 0) printf(theother side has been closed.\n); else Write(STDOUT_FILENO,buf, n); } Close(sockfd); return0; } 编译并运行server和client看看是否达到了你预想的结果。 这时server仍在运行但是client的运行结果并不正确。原因是什么呢仔细查看server.c可以发现server对每个请求只处理一次应答后就关闭连接client不能继续使用这个连接发送数据。但是client下次循环时又调用write发数据给serverwrite调用只负责把数据交给TCP发送缓冲区就可以成功返回了所以不会出错而server收到数据后应答一个RST段client收到RST段后无法立刻通知应用层只把这个状态保存在TCP协议层。client下次循环又调用write发数据给server由于TCP协议层已经处于RST状态了因此不会将数据发出而是发一个SIGPIPE信号给应用层SIGPIPE信号的缺省处理动作是终止程序所以看到上面的现象。 为了避免client异常退出上面的代码应该在判断对方关闭了连接后break出循环而不是继续write。另外有时候代码中需要连续多次调用write可能还来不及调用read得知对方已关闭了连接就被SIGPIPE信号终止掉了这就需要在初始化时调用sigaction处理SIGPIPE信号如果SIGPIPE信号没有导致进程异常退出write返回-1并且errno为EPIPE。 另外我们需要修改server使它可以多次处理同一客户端的请求。 [cpp] view plain copy /* server.c */ #include stdio.h #include string.h #include netinet/in.h #include wrap.h #define MAXLINE 80 #define SERV_PORT 8000 int main(void) { structsockaddr_in servaddr, cliaddr; socklen_tcliaddr_len; intlistenfd, connfd; charbuf[MAXLINE]; charstr[INET_ADDRSTRLEN]; inti, n; listenfd Socket(AF_INET, SOCK_STREAM, 0); bzero(servaddr,sizeof(servaddr)); servaddr.sin_family AF_INET; servaddr.sin_addr.s_addr htonl(INADDR_ANY); servaddr.sin_port htons(SERV_PORT); Bind(listenfd,(struct sockaddr *)servaddr, sizeof(servaddr)); Listen(listenfd,20); printf(Acceptingconnections ...\n); while(1) { cliaddr_len sizeof(cliaddr); connfd Accept(listenfd, (structsockaddr *)cliaddr, cliaddr_len); while(1) { n Read(connfd, buf, MAXLINE); if(n 0) { printf(theother side has been closed.\n); break; } printf(receivedfrom %s at PORT %d\n, inet_ntop(AF_INET,cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port)); for(i 0; i n; i) buf[i] toupper(buf[i]); Write(connfd,buf, n); } Close(connfd); } } 经过上面的修改后客户端和服务器可以进行多次交互了。 前面几篇中实现的client每次运行只能从命令行读取一个字符串发给服务器再从服务器收回来现在我们把它改成交互式的不断从终端接受用户输入并和server交互。 [cpp] view plain copy /* client.c */ #include stdio.h #include string.h #include unistd.h #include netinet/in.h #include wrap.h #define MAXLINE 80 #define SERV_PORT 8000 int main(int argc, char *argv[]) { structsockaddr_in servaddr; charbuf[MAXLINE]; intsockfd, n; sockfd Socket(AF_INET, SOCK_STREAM, 0); bzero(servaddr,sizeof(servaddr)); servaddr.sin_family AF_INET; inet_pton(AF_INET,127.0.0.1, servaddr.sin_addr); servaddr.sin_port htons(SERV_PORT); Connect(sockfd,(struct sockaddr *)servaddr, sizeof(servaddr)); while(fgets(buf, MAXLINE, stdin) ! NULL) { Write(sockfd,buf, strlen(buf)); n Read(sockfd, buf, MAXLINE); if(n 0) printf(theother side has been closed.\n); else Write(STDOUT_FILENO,buf, n); } Close(sockfd); return0; } 编译并运行server和client看看是否达到了你预想的结果。 这时server仍在运行但是client的运行结果并不正确。原因是什么呢仔细查看server.c可以发现server对每个请求只处理一次应答后就关闭连接client不能继续使用这个连接发送数据。但是client下次循环时又调用write发数据给serverwrite调用只负责把数据交给TCP发送缓冲区就可以成功返回了所以不会出错而server收到数据后应答一个RST段client收到RST段后无法立刻通知应用层只把这个状态保存在TCP协议层。client下次循环又调用write发数据给server由于TCP协议层已经处于RST状态了因此不会将数据发出而是发一个SIGPIPE信号给应用层SIGPIPE信号的缺省处理动作是终止程序所以看到上面的现象。 为了避免client异常退出上面的代码应该在判断对方关闭了连接后break出循环而不是继续write。另外有时候代码中需要连续多次调用write可能还来不及调用read得知对方已关闭了连接就被SIGPIPE信号终止掉了这就需要在初始化时调用sigaction处理SIGPIPE信号如果SIGPIPE信号没有导致进程异常退出write返回-1并且errno为EPIPE。 另外我们需要修改server使它可以多次处理同一客户端的请求。 [cpp] view plain copy /* server.c */ #include stdio.h #include string.h #include netinet/in.h #include wrap.h #define MAXLINE 80 #define SERV_PORT 8000 int main(void) { structsockaddr_in servaddr, cliaddr; socklen_tcliaddr_len; intlistenfd, connfd; charbuf[MAXLINE]; charstr[INET_ADDRSTRLEN]; inti, n; listenfd Socket(AF_INET, SOCK_STREAM, 0); bzero(servaddr,sizeof(servaddr)); servaddr.sin_family AF_INET; servaddr.sin_addr.s_addr htonl(INADDR_ANY); servaddr.sin_port htons(SERV_PORT); Bind(listenfd,(struct sockaddr *)servaddr, sizeof(servaddr)); Listen(listenfd,20); printf(Acceptingconnections ...\n); while(1) { cliaddr_len sizeof(cliaddr); connfd Accept(listenfd, (structsockaddr *)cliaddr, cliaddr_len); while(1) { n Read(connfd, buf, MAXLINE); if(n 0) { printf(theother side has been closed.\n); break; } printf(receivedfrom %s at PORT %d\n, inet_ntop(AF_INET,cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port)); for(i 0; i n; i) buf[i] toupper(buf[i]); Write(connfd,buf, n); } Close(connfd); } } 经过上面的修改后客户端和服务器可以进行多次交互了。