ioctl() FIONREAD 判断accept socketfd 返回错误 errno = 22

只此冒泡君 2019-09-24 04:53:26
在linux 下使用ioctl() FIONREAD 判断 tcp的监听fd 报错 errno为 22
ioctl(ptSocket->m_hSocket, FIONREAD, &nLength)
ptSocket->m_hSocket 为
socket()
bind()
listen()


我自己测试了一下把listen()注释掉ioctl是不返回错误的 ,难道listen之后socketfd的属性发生变化了?

我自己写了个demo,写的随便了一下 注释掉listen() 那一行就没问题
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

int main ()
{
int socketfd;
int nRet = -1;
int len;
int nOn;
int nYes;
int nkeepIdle = 5;
int nkeepInterval = 5;
int nkeepCount = 3;
struct sockaddr_in addr;

socketfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
setsockopt(socketfd, IPPROTO_TCP, TCP_NODELAY, (char*)&nOn, sizeof(int));
setsockopt(socketfd, SOL_SOCKET, SO_KEEPALIVE, (char*)&nYes, sizeof(int));
nRet = setsockopt(socketfd, SOL_TCP, TCP_KEEPIDLE, (void *)&nkeepIdle, sizeof(nkeepIdle));
nRet = setsockopt(socketfd, SOL_TCP, TCP_KEEPINTVL, (void *)&nkeepInterval, sizeof(nkeepInterval));
nRet = setsockopt(socketfd, SOL_TCP, TCP_KEEPCNT, (void *)&nkeepCount, sizeof(nkeepCount));
addr.sin_family = AF_INET;
addr.sin_port = htons(8000);
addr.sin_addr.s_addr = INADDR_ANY;
bind(socketfd, (struct sockaddr*)&addr, sizeof(addr));
listen(socketfd, 2);

nRet = ioctl(socketfd, FIONREAD, &len);
printf("the ret = %d, socket = %d, error = %d\n", nRet, socketfd, errno);
return 0;
}
...全文
1532 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
铖邑 2019-10-08
  • 打赏
  • 举报
回复
引用 10 楼 上班這麼困呢 的回复:
[quote=引用 9 楼 SuperDay 的回复:] 楼主都搞明白了吗?
没搞太明白,因为返回的是无效参数的错误,只可能是socket这个参数,估计listen之后导致socket属性不适用于FIONREAD检测了。[/quote] 不是这么操作的呀,之前有弄过这个代码
只此冒泡君 2019-10-08
  • 打赏
  • 举报
回复
引用 9 楼 SuperDay 的回复:
楼主都搞明白了吗?

没搞太明白,因为返回的是无效参数的错误,只可能是socket这个参数,估计listen之后导致socket属性不适用于FIONREAD检测了。
铖邑 2019-10-08
  • 打赏
  • 举报
回复
楼主都搞明白了吗?
铖邑 2019-10-08
  • 打赏
  • 举报
回复
引用 7 楼 上班這麼困呢 的回复:
[quote=引用 6 楼 SuperDay 的回复:]
[quote=引用 5 楼 上班這麼困呢 的回复:][quote=引用 3 楼 SuperDay 的回复:]
这个一般在accept之后得到的socket上面设置的吧

想了解一下为什么 用于accept的socket 不能用这种方法判断 ? [/quote]因为listen的那个socket实际上并没有IO[/quote]
在没有调用listen()之前,用ioctl 并不会报错,仅仅创建socket 和 bind 这时候socket上是否有IO 是listen将socket的属性改变了吗?[/quote]bind之后按理不会有IO,listen之后就只接受connect信号,不会有IO
只此冒泡君 2019-10-08
  • 打赏
  • 举报
回复
引用 6 楼 SuperDay 的回复:
[quote=引用 5 楼 上班這麼困呢 的回复:][quote=引用 3 楼 SuperDay 的回复:]
这个一般在accept之后得到的socket上面设置的吧

想了解一下为什么 用于accept的socket 不能用这种方法判断 ? [/quote]因为listen的那个socket实际上并没有IO[/quote]
在没有调用listen()之前,用ioctl 并不会报错,仅仅创建socket 和 bind 这时候socket上是否有IO 是listen将socket的属性改变了吗?
铖邑 2019-10-08
  • 打赏
  • 举报
回复
引用 5 楼 上班這麼困呢 的回复:
[quote=引用 3 楼 SuperDay 的回复:]
这个一般在accept之后得到的socket上面设置的吧

想了解一下为什么 用于accept的socket 不能用这种方法判断 ? [/quote]因为listen的那个socket实际上并没有IO
只此冒泡君 2019-10-08
  • 打赏
  • 举报
回复
引用 3 楼 SuperDay 的回复:
这个一般在accept之后得到的socket上面设置的吧

想了解一下为什么 用于accept的socket 不能用这种方法判断 ?
铖邑 2019-09-27
  • 打赏
  • 举报
回复
这个不需要看到源码才能解决的
铖邑 2019-09-26
  • 打赏
  • 举报
回复
这个一般在accept之后得到的socket上面设置的吧
只此冒泡君 2019-09-25
  • 打赏
  • 举报
回复
有大神帮忙看看 ioctl 和 listen 的源码 帮忙分析具体的原因
只此冒泡君 2019-09-24
  • 打赏
  • 举报
回复
顶顶顶

23,217

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧