mingw64设置socket非阻塞失败

使用mingw64(gcc版本11.3.0)编译64位软件,如下设置socket非阻塞模式会失败:


u_long nb = 1;
ret = ioctlsocket(fd, FIONBIO, &nb);
if (ret) {
    error = WSAGetLastError();
    /* error等于WSAEOPNOTSUPP(10045) */
}

https://stackoverflow.com/questions/16184830/why-socket-does-not-set-to-non-blocking-mode/16185001,试试真好了,看着是mingw中宏定义FIONBIO和原生的不同。

Windows原生winsock2.h定义


#define IOCPARM_MASK    0x7f            /* parameters must be < 128 bytes */
#define IOC_VOID        0x20000000      /* no parameters */
#define IOC_OUT         0x40000000      /* copy out parameters */
#define IOC_IN          0x80000000      /* copy in parameters */
#define IOC_INOUT       (IOC_IN|IOC_OUT)
/* 0x20000000 distinguishes new &
                                           old ioctl's */
#define _IO(x,y)        (IOC_VOID|((x)<<8)|(y))
#define _IOR(x,y,t)     (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define _IOW(x,y,t)     (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))

#define FIONBIO         _IOW('f', 126, u_long) /* set/clear non-blocking i/o */

mingw64中winsock2.h定义


#define IOCPARM_MASK 0x7f
#define IOC_VOID 0x20000000
#define IOC_OUT 0x40000000
#define IOC_IN 0x80000000
#define IOC_INOUT (IOC_IN|IOC_OUT)

#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
#define _IOR(x,y,t) (IOC_OUT|(((__LONG32)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define _IOW(x,y,t) (IOC_IN|(((__LONG32)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))

#define FIONBIO _IOW('f',126,u_long)

两者看上去存在__LONG32long的不同,实测发现mingw64环境下FIONBIO等于0x8008667E,而不是期望的0x8004667E,这是由于mingw64中u_long是8个字节导致。

作者:hubugui
来源:黑骄客
原文:https://mp.weixin.qq.com/s/HVK7DYCJPuXJ6ZH1xgR8IQ

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论