上节在图片传输中,在主线程main中加入了epoll,结果和上上节的图片传输一结合,各种问题。
【问题】:将套接字设置成非阻塞,然后在epoll检测到sockfd有新数据时创建线程进行处理。然后问题来了,小图片第一次传输成功,第二次传输不成功;大图片一次传输都不成功;服务端图片size第一次打印正常 ,第二次打印乱码。
【解决步骤1】:于是将图片换成内容全是1和全是2的文本文件,来帮助检测。果然:第二次读size时,读的是缓冲区中文件2的内容2222222222
小文件由于size小于缓冲区size,所以一次读完了,传输正常。而大文件由于size大于缓冲区size,所以需要发送多次。
可为什么会每次都write done呢?我明明在servluo_match中read写了循环啊
打印了一下每次的bytes,发现只出现一次,然后定睛一看:bytes=-rd;代码错了,改成bytes-=rd;就正常了:
大文件发送成功了,但为什么后面会跟那么多空白的bytes=0呢???用gdb打印了一下线程信息
靠!!!!为什么有2个以上的线程????epoll搞得鬼!!!!每次新数据到达,epoll都会为socket分配一个线程来读数据,但是由于先前的线程读完了数据,所以后来的线程读到的全是空数据,并且一直悬空在那里。
那怎么才能让一个socket只让一个线程来读?EPOLLONESHOT,该socket的事件只触发一次
这下正常了
EPOLLONESHOT表示该socket的事件我只通知一次,那么这同样意味着同一个客户端向服务器提交多次请求时,只有第一次请求有效。如最上的那个客户端提交了两次,但只有第一次的请求得到了满足。
这下得改写客户端的代码了,传输一次后,等待服务器端检索,服务器端检索完,将数据发给客户端,客户端接收到数据,完成一次请求,断开连接。即将客户端改为一次检索请求,建立一次TCP连接,完成请求就断开连接。需要请求时再建立TCP连接。
那么问题又来了,客户端closeTCP后,怎样才能将事件从EPOLL中移除呢???????