Linux C++ 回射服务器
来源:互联网 发布:js获取两位小数函数 编辑:程序博客网 时间:2024/05/21 17:04
回射服务器就是服务端将客户端的数据发送回去。
我实现的回射服务器返回增加了时间。
服务端代码,可以很容易看懂:
#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 512typedef 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); //创建线程池 threadpool<task> 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;}
下面的是客户端的代码:
#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文件来测试:
#!/bin/bashfor i in `seq 2000` do ./client.out 127.0.0.1 8989done
循环 执行2000次。
第二个shell文件:
#!/bin/bash./loop.sh > file1 &./loop.sh > file2 &./loop.sh > file3 &./loop.sh > file4 &./loop.sh > file5 &wait开启5个进程来返问。
执行第二个shell文件
最终,耗时为:
real0m7.589suser0m0.460ssys0m1.944s
而且五个File文件中,有Hello的行数数都为2000.
下一篇是实现一个简单小型的web服务器。
0 0
- Linux C 时间服务器
- Linux fork() socket并发回射服务器实现(c)
- Linux C++ 回射服务器
- SSH连接远程Linux服务器(C#)
- SSH连接远程Linux服务器(C#)
- linux c 实现简单版 ftp 服务器
- SSH连接远程Linux服务器(C#)
- c linux服务器简单http server程序
- [linux] c 实现简单的web服务器
- linux c 实现简易HTTP服务器
- Linux C TCP服务器收不到报文
- Linux下回射服务器
- 【C语言】linux下c语言 客户端服务器编程框架
- VS2013 C语言(C++)连接linux的MySQL服务器
- 【linux/c/c++】linux 的服务器环境安装支持c/c++等操作
- 转 开源Granados介绍 - SSH连接远程Linux服务器(C#)
- 用C语言实现的简单Web服务器(Linux)
- 开源Granados介绍 - SSH连接远程Linux服务器(C#)
- BZOJ4514: [Sdoi2016]数字配对
- hdu5988 Coding Contest
- 碰撞(Collision)和触发事件(Trigger)
- Git使用总结!
- Go goroutine同步
- Linux C++ 回射服务器
- js正则匹配出所有图片及所有图片地址src
- MyBatis学习之动态SQL标签
- ssm框架整合时,服务器启动时报警告
- 静态代理与动态代理
- cvtColor彩色空间转换-------opencv2.4.11(Java)
- 约瑟夫go实现
- Petri网之XML文件设计代码(传入一个矩阵生成Petri网)
- 关于ARM的22个常用概念介绍