from https://stackoverflow.com/questions/5039608/poll-cant-detect-event-when-socket-is-closed-locally

I'm working on a project that will port a TCP/IP client program onto an embedded ARM-Linux controller board. The client program was originally written in epoll(). However, the target platform is quite old; the only kernel available is 2.4.x, and epoll() is not supported. So I decided to rewrite the I/O loop in poll().

But when I'm testing code, I found that poll() does not act as I expected : it won't return when a TCP/IP client socket is closed locally, by another thread. I've wrote a very simple codes to do some test:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <pthread.h>
#include <poll.h> struct pollfd fdList[1]; void *thread_runner(void *arg)
{
sleep(10);
close(fdList[0].fd);
printf("socket closed\n");
pthread_exit(NULL);
} int main(void)
{
struct sockaddr_in hostAddr;
int sockFD;
char buf[32];
pthread_t handle; sockFD = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sockFD,F_SETFL,O_NONBLOCK|fcntl(sockFD,F_GETFL,0)); inet_aton("127.0.0.1",&(hostAddr.sin_addr));
hostAddr.sin_family = AF_INET;
hostAddr.sin_port = htons(12345);
connect(sockFD,(struct sockaddr *)&hostAddr,sizeof(struct sockaddr)); fdList[0].fd = sockFD;
fdList[0].events = POLLOUT; pthread_create(&handle,NULL,thread_runner,NULL); while(1) {
if(poll(fdList,1,-1) < 1) {
continue;
}
if(fdList[0].revents & POLLNVAL ) {
printf("POLLNVAL\n");
exit(-1);
}
if(fdList[0].revents & POLLOUT) {
printf("connected\n");
fdList[0].events = POLLIN;
}
if(fdList[0].revents & POLLHUP ) {
printf("closed by peer\n");
close(fdList[0].fd);
exit(-1);
}
if(fdList[0].revents & POLLIN) {
if( read(fdList[0].fd, buf, sizeof(buf)) < 0) {
printf("closed by peer\n");
close(fdList[0].fd);
exit(-1);
}
}
}
return 0;
}

 

In this code I first create a TCP client socket, set to non-blocking mode, add to poll(), and close() the socket in another thread. And the result is: "POLLNVAL" is never printed while the socket is closed.

Is that an expected behavior of poll() ? Will it help if I choose select() instead of poll() ?

Answer:

Yes, this is expected behavior. You solve this by using shutdown() on the socket instead of close().

See e.g. http://www.faqs.org/faqs/unix-faq/socket/ section 2.6

EDIT: The reason this is expected is that poll() and select() reacts to events happening on one of their fd's. close() removes the fd, it does not exist at all anymore, and thus it can't have any events associated with it.

It worked. poll() will return with POLLHUP event

 

poll() can't detect event when socket is closed locally?的更多相关文章

  1. java的Socket通信例子及关于java.net.SocketException: Socket is closed错误

    今天写socket数据相互通信的时候,碰到一个及其蛋疼的错误.单向传输数据的时候server与client是没有问题的,但是两个都有输入输出操作的时候就出现了这个问题 java.net.SocketE ...

  2. java.io.IOException: read failed, socket might closed or timeout, read ret: -1

    近期项目中连接蓝牙之后接收蓝牙设备发出的指令功能,在连接设备之后,创建RfcommSocket连接时候报java.io.IOException: read failed, socket might c ...

  3. paramiko 遭遇socket.error: Socket is closed 错误的解决办法

    似乎是connection自己断了解决的办法是在创建conn的时候添加下面这句 conn.keep_this = conn_session 完整代码 def create_a_conn(ip_addr ...

  4. vue app混合开发蓝牙串口连接(报错java.io.IOException: read failed, socket might closed or timeout, read ret: -1;at android.bluetooth.BluetoothSocket.connect at js/BluetoothTool.js:329)

    我使用的uni-app <template> <view class="bluetooth"> <!-- 发送数据 --> <view c ...

  5. The socket is closed!

    关闭mongodb    /usr/local/app/mongidb//bin/mongod   --shutdown  --dbpath /usr/local/data/mongo/data/ 然 ...

  6. 转:sock_ev——linux平台socket事件框架(event loop) .

    上一篇我们封装了三种事件监听方式,如果分别提供给客户端使用,有点不方便,也不利于统一管理:我们再封装一层EventLoop. /************************************ ...

  7. Linux内核3.11的socket busy poll机制避免睡眠切换

    Linux的网络协议栈很独立,上下通过两个接口分别和用户态以及设备相连.也能够看作是北向和南向接口...北向通过socket接口,南向通过qdisc接口(你能够觉得是上层的netdev queue,对 ...

  8. Asynchronous socket communication

    来源:http://www.codeproject.com/Articles/1608/Asynchronous-socket-communication 本地下载 Download source f ...

  9. #include <sys/epoll.h> epoll - I/O event notification facility 服务器端 epoll(7) - Linux manual page http://www.man7.org/linux/man-pages/man7/epoll.7.html

    epoll使用详解(精髓) - Boblim - 博客园 https://www.cnblogs.com/fnlingnzb-learner/p/5835573.html epoll使用详解(精髓) ...

随机推荐

  1. 什么是BS,BS和CS的区别有哪些

    BS和CS的区别以及优缺点 C/S又称Client/Server或客户/服务器模式.服务器通常采用高性能的PC.工作站或小型机,并采用大型数据库系统,如Oracle.Sybase.Informix或 ...

  2. HTTP::UserAgent注意问题

    例用 HTTP::Request 设置头信息时, 比如 add-content , 第二次再执行 add-content 时, content 内容会追加, 并不会重新添加. 当下次再 add-con ...

  3. 查看nginx | apache | php | tengine | tomcat版本的信息以及如何隐藏版本信息【转】

    转自: 查看nginx | apache | php | tengine | tomcat版本的信息以及如何隐藏版本信息 - 追马 - 51CTO技术博客http://lovelace.blog.51 ...

  4. 升级Chrome后无法打开网页

    最近升级了网站,发现很多普通网站Chrome 都打不开了....  IE  可以正常打开,很是郁闷,重启电脑都不行. chrome://net-internals/#dns 点击如下按钮 清楚DNS缓 ...

  5. Linux屏幕记录命令script

    Script -a action.log –t 2> time.log按ctrl+d 退出录制回访 scriptreplay time.log action.log或者直接用查看命令cat,ta ...

  6. 【LOJ】#2264. 「CTSC2017」吉夫特

    题解 根据一番认真严肃的猜结论和打表证明之后 我们可以得到 \(f[i] = (\sum_{a[i] \& a[j] == a[j]} f[j]) + 1\) 统计所有的\(f[i] - 1\ ...

  7. IO知识点整理(文件File类的使用)

    一: 1.API 2.构造函数的程序 注意这集中构造函数的特点. 同时,字段separator的使用. import java.io.File; public class Test101 { publ ...

  8. 谈谈MySQL中的降序索引 order by id DESC / ASC

    今天这篇主要讲order by 语句中的多个字段asc desc的问题.mysql5中,索引存储的排序方式是ASC的,没有DESC的索引.现在能够理解为啥order by 默认是按照ASC来排序的了吧 ...

  9. 洛谷P2894 [USACO08FEB]酒店Hotel [线段树]

    题目传送门 酒店 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...

  10. js文字转语音并播放

    这里调用的是百度文字转语音开放API html: <div> <input type="text" id="ttsText"> < ...