注册网站域名要钱吗,seo关键词排名优化品牌,网站做邮箱吗,自豪的使用WordPresshttp://blog.csdn.net/qq_25425023/article/details/53914820回射服务器就是服务端将客户端的数据发送回去。我实现的回射服务器返回增加了时间。服务端代码#xff0c;可以很容易看懂#xff1a;[cpp] view plaincopy#include sys/socket.h #include stdio.h可以很容易看懂[cpp] view plain copy#include sys/socket.h #include stdio.h #include string.h #include sys/types.h #include netinet/in.h #include time.h #include unistd.h #include arpa/inet.h #include stdlib.h #include ../thread_pool.h //在上一篇博客中 #define MAX_BUFFER 512 typedef struct sockaddr SSA; char timebuffer[50]; //存储时间 char readbuffer[MAX_BUFFER]; //存储客户端数据 time_t tick; //任务类 class task { private: int connfd; //与客户端连接的文件描述符 public: task(int conn) : connfd(conn) { } ~task(){} void doit() //线程池调用函数 { size_t readsize; while((readsize read(connfd, readbuffer, MAX_BUFFER)) 0) //读取客户端数据 { printf(%ld get %dbyte\n,(unsigned long)pthread_self() , (int)readsize); //测试用 if(readsize -1) //read出错 { printf(errno is %s\n, strerror(errno)); //这里输出onnection reset by peer continue; } readbuffer[readsize] \0; tick time(NULL); //获取时间 snprintf(timebuffer, sizeof(timebuffer), time : %.24s\r\n, ctime(tick)); strcat(readbuffer, timebuffer); //时间与客户数据连接到一起 write(connfd, readbuffer, strlen(readbuffer)); //发送给客户端 } // printf(close the connfd\n); // fflush(stdout); close(connfd); } }; int main(int argc, char *argv[]) { if(argc ! 2) { printf(uasge : %s port, argv[0]); exit(-1); } int sockfd, connfd; struct sockaddr_in serv_addr, cli_addr; int port atoi(argv[1]); //初始化sockaddr_in serv_addr.sin_family AF_INET; serv_addr.sin_port htons(port); serv_addr.sin_addr.s_addr htonl(INADDR_ANY); //允许任何人连接 //创建套接字 sockfd socket(AF_INET, SOCK_STREAM, 0); if(sockfd 0) { printf(socket error n); exit(-1); } //绑定 bind(sockfd, (SSA *)serv_addr, sizeof(serv_addr)); //监听套接字 listen(sockfd, 6); //创建线程池 threadpooltask pool(60, 100); pool.start(); //开启线程池 while(1) { socklen_t len sizeof(cli_addr); connfd accept(sockfd, (SSA *)cli_addr, len); //接受连接 task *ta new task(connfd); //新建任务 char buf[20]; printf(IP %s conn\n, inet_ntop(AF_INET, cli_addr.sin_addr, buf, sizeof(buf))); while(!pool.append_task(ta)) //添加任务到任务队列 printf(loop\n); //测试用 } return 0; } 下面的是客户端的代码[cpp] view plain copy#include stdio.h #include sys/socket.h #include arpa/inet.h #include string.h #include sys/types.h #include unistd.h #include netinet/in.h #include stdlib.h int main(int argc, char *argv[]) { if(argc ! 3) //参数不对退出 { printf(usage: %s ip port\n, argv[0]); exit(-1); } int sockfd; struct sockaddr_in serv_addr; int port atoi(argv[2]); //将字符串的端口转换称int //初始化服务端的端口和IP地址 serv_addr.sin_family AF_INET; serv_addr.sin_port htons(port); //将主机字节序转换称网络字节序 inet_pton(AF_INET, argv[1], serv_addr.sin_addr); //创建套接字 sockfd socket(AF_INET, SOCK_STREAM, 0); //连接 connect(sockfd, (struct sockaddr *)serv_addr, sizeof(serv_addr)); char buffer[50]; write(sockfd, hello\n, 6); //写数据 shutdown(sockfd, SHUT_WR); //解释在下面 size_t num read(sockfd, buffer, sizeof(buffer)); //读数据 buffer[num] \0; printf(read: %s\n, buffer); shutdown(sockfd, SHUT_RD); // close(sockfd); return 0; } 客户端一开始我使用的是最后来个close的就是注释那部分但是多个连接同时来的时候服务端会出错具体的出错信息是Connection reset by peer重新执行read之后得到Hello的个数没有少也就是客户端发送的个数。然而我客户端写完数据就关闭写端读取完数据再关闭读端就不会出现这样的错误。
具体原因还不是很清楚网上没有查找到具体的答案。求大神来解答~~终于知道原因了出错的是在服务端的read函数read返回-1而在客户端发送完数据就shutdown写端发送完数据就会发送FIN包服务端read返回0因为read不止被调用一次第一次读取完数据之后继续读取可是客户端没有数据可读就会出错而提前关闭客户端写端所以read那里的WHILE退出就没有了出错的信息。同时写了两个shell文件来测试:[html] view plain copy#!/bin/bash for i in seq 2000 do ./client.out 127.0.0.1 8989 done 循环 执行2000次。第二个shell文件[html] view plain copy#!/bin/bash ./loop.sh file1 ./loop.sh file2 ./loop.sh file3 ./loop.sh file4 ./loop.sh file5 wait 开启5个进程来返问。执行第二个shell文件
最终耗时为[html] view plain copyreal 0m7.589s user 0m0.460s sys 0m1.944s 而且五个File文件中有Hello的行数数都为2000.下一篇是实现一个简单小型的web服务器。