查看socket fd状态,设置nonblock
# 将socket设置为非阻塞(non-blocking)
https://blog.csdn.net/SprintfWater/article/details/9232073 (opens new window)
有一个非常有迷惑性的做法是: u_long has = 1; ioctl(m_sock, FIONBIO , &has); 这个函数会非常无耻的返回你success,但是它实际上很可能什么也没做。
正确的做法应该是使用fcntl: int flags = fcntl(m_sock, F_GETFL, 0); fcntl(m_sock, F_SETFL, flags|O_NONBLOCK);
这真是一个隐蔽的问题,折腾了我两天。线程每每停留在send()调用那里,我始终没怀疑到:用ioctl设置FIONBIO成功之后,socket竟然还是阻塞的。
# 查看是否为non-blocking
#include <fcntl.h>
int flags = fcntl(s, F_GETFL, 0);
printf("flags&O_NONBLOCK=%x, O_NONBLOCK=%x, flags=%x\n", flags&O_NONBLOCK, O_NONBLOCK, flags);
//flags&O_NONBLOCK=800, O_NONBLOCK=800, flags=802
1
2
3
4
5
6
7
2
3
4
5
6
7
# fcntl()
https://man7.org/linux/man-pages/man2/fcntl.2.html (opens new window)
FCNTL(2) Linux Programmer's Manual FCNTL(2)
NAME top
fcntl - manipulate file descriptor
SYNOPSIS top
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
DESCRIPTION top
fcntl() performs one of the operations described below on the
open file descriptor fd. The operation is determined by cmd.
fcntl() can take an optional third argument. Whether or not this
argument is required is determined by cmd. The required argument
type is indicated in parentheses after each cmd name (in most
cases, the required type is int, and we identify the argument
using the name arg), or void is specified if the argument is not
required.
Certain of the operations below are supported only since a
particular Linux kernel version. The preferred method of
checking whether the host kernel supports a particular operation
is to invoke fcntl() with the desired cmd value and then test
whether the call failed with EINVAL, indicating that the kernel
does not recognize this value.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
编辑 (opens new window)
上次更新: 2023/05/07, 17:27:54