记录一个写epoll负载发生器时遇到的问题

就是一个负载测试的程序,用epoll写的,然后被测试的回射服务器也是用epoll写的

这里假设负载是20个socket连接

客户端的操作是一次性把20个连接连上(socket, connect),然后发20个数据,再接20个数据

服务器的动作是,循环20次 新增连接(accept)->接数据->回射数据

当客户端接受到20次数据的时候会把所有的sockfd全close掉,epfd也close

这时候服务器端就会接收到一个SIGPIPE信号,这个报错是当一个进程向某个已收到RST的套接字执行写操作时,内核向该进程发送的。信号默认的行为是终止进程。

RST信号是当服务器TCP接收到来自客户的数据时,服务器端先前打开的那个套接字的进程已经终止,于是相应一个RST。

也就是说

服务器接收到了SIGPIPE信号,并且服务器也收到了一个RST信号

这个RST信号是服务器向客户端写数据但发现客户端连接已终止的时候产生的

那么,测了测发现还是服务器多向客户端写数据了

应该是服务器端监听可写的问题,即使是ET模式也不行,因为当缓冲区中数据取走之后变为可写状态服务器端也会返回,这样就多了一个返回出来。

虽然不知道发送了什么数据过去,但是解决方法是,在服务器发送完数据之后把监听DEL掉。

现在测一下发送了什么数据。

发送的是空数据,但是由于write时写的大小是sizeof(buf),导致发送过去是MAXLINE大小的空数据

改为strlen(buf)之后问题解决了一部分。

应该就是缓冲区数据变化导致服务器监听可写状态的端口一直返回可写标志导致的。

if( write(events[i].data.fd, buf, n) <= 0)

改为

if( write(events[i].data.fd, buf, strlen(buf)) <= 0)

之后少了20个成功发送的标志,还有20个发送失败

应该是客户端那边读取数据之后,服务器又接到一个可写标志,又向里面写导致的。

附sizeof()和strlen()区别

、sizeof sizeof(…)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。 它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。 由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。实际上,用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。 具体而言,当参数分别如下时,sizeof返回的值表示的含义如下: 数组——编译时分配的数组空间大小; 指针——存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为4); 类型——该类型所占的空间大小; 对象——对象的实际占用空间大小; 函数——函数的返回类型所占的空间大小。函数的返回类型不能是void。

、strlen strlen(…)是函数,要在运行时才能计算。参数必须是字符型指针(char*)。当数组名作为参数传入时,实际上数组就退化成指针了。 它的功能是:返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。

猜你喜欢

转载自blog.csdn.net/qq_24889575/article/details/81736190
今日推荐