Windows的网络编程-之五-套接字选项和I/O控制
2012-01-02 16:45
363 查看
1 套接字选项和I/O控制
1.1 套接字选项
intgetsockopt( SOCKET s, int level, int optname, char* optval, int* optlen );intsetsockopt( SOCKET s, int level, int optname, const char* optval, int optlen );
1.1.1 SOL_SOCKET选项级别
1.1.1.1 SO_ACCEPTCONN
选项值类型 | get/set | Winsock | 说明 |
bool | get | 1+ | 如果已通过listen( )将套接字置入监听模式, 这个选项就会返回TRUE。 |
1.1.1.2 SO_BROADCAST
选项值类型 | get/set | Winsock | 说明 |
bool | get/set | 1+ | TRUE,套接字可以收发广播数据 |
要想接收一条广播消息,首先必须启用广播选项,然后使用某个数据报接收函数recvfrom( )或WSARecvfrom()。另外一种方法是把套接字通过调用connect( )或WSAConnect()与广播地址连接起来,再调用recv( )或WSARecv( )来实现的。对UDP广播来说,必须指定一个端口号,以便向它发送数据报;接收端也必须请求在这个端口上接收广播数据。对UDP来说,存在着一个特殊的广播地址,所有广播数据均应发至该地址。这个地址便是255.255.255.255。
通常,只有在发送广播数据报时,才需要设置SO_BROADCAST选项。要想接收一个广播数据报,只需在指定的端口上,对进入的数据报进行监听即可。
1.1.1.3 SO_CONNECT_TIME
选项值类型 | get/set | Winsock | 说明 |
int | get | 1+ | 返回套接字建立连接的时间,以秒为单位 |
1.1.1.4 SO_DONTROUTE
选项值类型 | get/set | Winsock | 说明 |
bool | get/set | 1+ | 如果是TRUE,忽略路由表的存在, 通过套接字绑定的那个接口直接将数据传送出去。 |
1.1.1.5 SO_EXCLUSIVEADDRUSE
选项值类型 | get/set | Winsock | 说明 |
bool | get/set | 2+ | 如果是TRUE,套接字绑定的那个本地端口 就不能重新被另一个进程使用 |
1.1.1.6 SO_KEEPALIVE
选项值类型 | get/set | Winsock | 说明 |
bool | get/set | 1+ | 如果是TRUE,套接字就会在会话过程中发送keepalive消息 |
1.1.1.7 SO_LINGER
选项值类型 | get/set | Winsock | 说明 |
struct linger | get/set | 1+ | 设置或获取当前的拖延时间 |
SO_LINGER用于控制在执行closesocket()后,套接字上正在排队的数据如何处理。
typedefstruct linger
{
u_short l_onoff; // 是否linger
u_short l_linger; // 单位是秒
}linger;
若l_onoff是一个非零值,l_linger指定一段拖延时间,此时的关闭方式称为从容关闭,closesocket( )会在一个阻塞套接字上进入阻塞状态,直到剩余的数据全部发出或接收。如果超过规定的时间,所有尚未发送或接收的数据都会丢弃。
如果假如l_onoff是一个非零值,但l_linger为0,此时的关闭方式称为强行关闭,便不用担心closesocket( )会进入阻塞状态,即使队列中的数据尚未发送或者尚未发出收到确认。
1.1.1.8 SO_MAX_MSG_SIZE
选项值类型 | get/set | Winsock | 说明 |
unsigned int | get | 2+ | 获取消息的最大长度 |
1.1.1.9 SO_PROTOCOL_INFO
选项值类型 | get/set | Winsock | 说明 |
WSAPROTOCOL_INFO | get | 2+ | 获取套接字协议的特征 |
1.1.1.10 SO_RCVBUF
选项值类型 | get/set | Winsock | 说明 |
int | get/set | 1+ | 用于返回或设置分配给套接字的接收缓冲区大小 |
1.1.1.11 SO_REUSEADDR
选项值类型 | get/set | Winsock | 说明 |
bool | get/set | 1+ | 如果是TRUE,套接字就可以和正被使用的地址绑定到一起, 或与处在TIME_WAIT状态的地址绑定到一起 |
1.1.1.12 SO_SNDBUF
选项值类型 | get/set | Winsock | 说明 |
int | get/set | 1+ | 用于返回或设置分配给套接字的发送缓冲区大小 |
1.1.1.13 SO_TYPE
选项值类型 | get/set | Winsock | 说明 |
int | get | 1+ | 返回指定套接字的类型 |
1.1.1.14 SO_SNDTIMEO
选项值类型 | get/set | Winsock | 说明 |
int | get/set | 1+ | 获取或设置阻塞套接字上的数据发送超时时间(毫秒) |
1.1.1.15 SO_RCVTIMEO
选项值类型 | get/set | Winsock | 说明 |
int | get/set | 1+ | 获取或设置阻塞套接字上的数据接收超时时间(毫秒) |
1.1.1.16 SO_OOBINLINE
选项值类型 | get/set | Winsock | 说明 |
bool | get/set | 1+ | 如果是TRUE, 带外数据就会以内嵌方式在普通数据流中返回 |
默认情况下,带外数据不是内嵌传送的,也就是说如果设置MSG_OOB标志调用一个接收函数,便会读取OOB数据。
如果设置了这个选项,OOB数据就会出现在一个接收函数返回的数据流中。
1.1.2 IPPROTO_IP选项级别
1.1.2.1 IP_OPTIONS
选项值类型 | get/set | Winsock | 说明 |
char[ ] | get/set | 1+ | 设置或获取IP头中的可选选项部分 |
代码 | 长度 | 偏移 | 选项数据 |
1 byte | 1 byte | 1 byte | 37 byte |
长度字段指定IP选项头的长度。
偏移字段指定数据部分的起始偏移位置。
在下面的代码中,我们设置一个记录路由的选项。注意:我们定义的结构只占用了39字节。系统会自动进行填充,将其长度保持为一个字(32 bit)的整数倍。
struct ip_option_hdr
{
unsigned char code; //1个字节
unsigned char length; //1个字节
unsigned char offset; //1个字节
unsigned long addrs[9]; //36个字节
} opthdr;
……;
memset( &opthdr, 0, sizeof(opthdr) );
opthdr.code=0x7;
opthdr.length=39;
opthdr.offset=4;
ret = setsockopt( s, IPPROTO_IP,IP_OPTIONS, (char *)&opthdr, sizeof(opthdr) );
1.1.2.2 IP_HDRINCL
选项值类型 | get/set | Winsock | 说明 |
bool | get/set | 2+ | 如果是TRUE,发送函数会将IP头包括在发送数据的前面, 所以接收函数获取的数据也包括IP头。 |
1.1.2.3 IP_TOS
选项值类型 | get/set | Winsock |
int | get/set | 1+ |
1.1.2.4 IP_TTL
选项值类型 | get/set | Winsock |
int | get/set | 1+ |
1.1.2.5 IP_MULTICAST_IF
选项值类型 | get/set | Winsock | 说明 |
unsigned long | get/set | 1+ | 获取或设置发送多播数据的接口 |
unsigned long mcastIF = inet_addr("129.113.43.128");
ret = setsockopt( s, IPPROTO_IP, IP_MULTICAST_IF, (char*)&mcastIF, sizeof(mcastIF) );
1.1.2.6 IP_MULTICAST_TTL
选项值类型 | get/set | Winsock |
int | get/set | 1+ |
1.1.2.7 IP_MULTICAST_LOOP
选项值类型 | get/set | Winsock | 说明 |
bool | get/set | 1+ | 如果是TRUE,多播数据将返回套接字 |
1.1.2.8 IP_ADD_MEMBERSHIP
选项值类型 | get/set | Winsock | 说明 |
struc ip_mreq | set | 1+ | 将套接字加入一个指定的IP多播组 |
structip_mreg
{
struct in_addr imr_multiaddr;
struct in_addr imr_interface;
};
1.1.2.9 IP_DROP_MEMBERSHIP
选项值类型 | get/set | Winsock | 说明 |
struct ip_mreq | set | 1+ | 将套接字从指定的IP组内删去 |
1.1.2.10 IP_DONTFRAGMENT
选项值类型 | get/set | Winsock | 说明 |
bool | get/set | 1+ | 如果是TRUE,就不对IP数据报进行分段 |
1.2 标准I/O控制命令
intioctlsocket( SOCKETs, long cmd, u_long* argp );intWSAIoctl( SOCKET s, DWORD dwIoControlCode,
LPVOIDlpvInBuffer, DWORD cbInBuffer,
LPVOIDlpvOutBuffer, DWORD cbOutBuffer,
LPDWORDlpcbBytesReturned,
LPWSAOVERLAPPEDlpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINElpCompletionRoutine
);
参数lpcbBytesReturned是实际返回的字节数。
1.2.1 FIONBIO
函数 | 输入 | 输出 | Winsock | 说明 |
两者均可 | unsigned long | 无 | 1+ | 将套接字设为非阻塞模式 |
若设为非阻塞模式,输入值设为一个非零值。
若设为阻塞模式,输入值设为0。
WSAAsyncSelect( )或WSAEventSelect( )会将套接字自动设为非阻塞模式,并且都无法直接使用ioctlsocket( )或WSAIoctl()重新设置为阻塞模式。要想将套接字改回阻塞模式,首先必须禁止WSAAsyncSelect( )或WSAEventSelect( ),具体做法是调用WSAAsyncSelect(),同时令其lEvent参数等于0。或者调用WSAEventSelect( ),同时令其lNetworkEvents参数等于0。
1.2.2 FIONREAD
函数 | 输入 | 输出 | Winsock | 说明 |
两者均可 | 无 | unsigned long | 1+ | 返回准备在套接字上读取的数据量 |
若套接字类型为SOCK_DGRAM,返回的是在套接字上排队的第一条消息的大小。
1.2.3 SIOCATMARK
函数 | 输入 | 输出 | Winsock | 说明 |
两者均可 | 无 | bool | 1+ | 判断是否准备读取带外数据 |
1.2.4 其他I/O控制选项(Winsock2特有)
1.2.4.1 SIO_ENABLE_CIRCULAR-QUEUEING
函数 | 输入 | 输出 | 说明 |
WSAIoctl | bool | bool | 若接收缓冲区队列溢出,则首先丢弃最早收到的消息 |
默认情况下,若接收缓冲区满了,以后新收到的消息会被丢弃。
1.2.4.2 SIO_FIND_ROUTE
函数 | 输入 | 输出 | 说明 |
WSAIoctl | SOCKADDR | bool | 验证到指定地址的路由是否存在 |
1.2.4.3 SIO_FLUSH
函数 | 输入 | 输出 | 说明 |
WSAIoct1 | 无 | 无 | 清除发送队列的内容 |
1.2.4.4 SIO_BROADCAST_ADDRESS
函数 | 输入 | 输出 | 说明 |
WSAIoctl | 无 | SOCKADDR | 返回一个广播地址,可在sendto或WSASendTo中使用 |
1.2.4.5 SIO_CHK_QOS
函数 | 输入 | 输出 | 说明 |
WSAIoctl | 无 | DWORD | 返回套接字的QoS状态 |
ALLOWED_TO_SEND_DATA
ALLOWED_TO_SEND_DATA用在QoS等级建立好之后(使用SIO_SET_QOS建立),但又没有收到任何RSVP预约请求(RESV)消息之前。若收到一条RESV消息,意味着请求的带宽已经分配给套接字。在收到RESV消息之前,对套接字的数据只会提供Best-Effort的服务。
利用ALLOWED_TO_SEND_DATA标志,可以查询Best-Effort的服务是否足够保证由SIO_SET_QOS请求的QoS服务等级。如果返回1,意味着Best-Effort已经足够使用;如果返回0,意味着Best-Effort尚不足以保证请求的服务等级。若ALLOWED_TO_SEND_DATA标志的返回值是0,那么作为发送方的应用程序,应在发出数据之前,等候一条RESV消息的抵达。
ABLE_TO_RECV_RSVP
ABLE_TO_RECV_RSVP指出主机是否能够在套接字绑定的接口上接收与处理RSVP消息。
LINE_RATE
LINE_RATE返回Best-Effort能使通信速率达到多少,单位是kbit/s。
若线路的通信速率未知,便返回INFO_NOT_AVAIABLE。
LOCAL_TRAFFIC_CONTROL 判断本地主机是否安装通信控制组件,是否能够使用
LOCAL_QOSABILITY 判断本地主机是否支持QoS
END_TO_END_QOSABILITY 判断整个本地网络是否支持QoS
若返回1,表明对应的功能是支持的;
若返回0,表明不支持;
若返回INFO_NOT_AVAIABLE,表明没有办法检查。
1.2.4.6 SIO_GET_QOS
函数 | 输入 | 输出 | 说明 |
WSAIoctl | 无 | QOS | 返回套接字的QOS |
1.2.4.7 SIO_SET_QOS
函数 | 输入 | 输出 | 说明 |
WSAIoctl | QOS | 无 | 设置套接字的QOS |
1.2.4.8 SIO_MULTIPOINT_LOOPBACK
函数 | 输入 | 输出 | 说明 |
WSAIoctl | bool | bool | 设置或查询多播数据是否返回套接字 |
1.2.4.9 SIO_MULTICAST_SCOPE
函数 | 输入 | 输出 | 说明 |
WSAIoctl | int | int | 设置或获取多播数据的TTL |
1.2.4.10 SIO_KEEPLIVE_VALS
函数 | 输入 | 输出 | 说明 |
WSAIoctl | tcp_keepalive | tcp_keepalive | 设置keepalive消息的发送周期 |
但使用SIO_KEEPLIVE_VALS便可针对每一个套接字设置keepalive消息发送周期。
structtcp_keepalive
{
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
};
keepalivetime和keepaliveinterval的单位都是毫秒。其中,keepaliveinterval指定发送keepalive消息的间隔时间,直至收到一个响应;keepalivetime用于控制keepalive数据包的发送频率,以查验一个连接是否仍然有效。
1.2.4.11 SIO_RCVALL
函数 | 输入 | 输出 | 说明 |
WSAIoctl | bool | 无 | 如果设为TRUE,接收网络上的所有数据包 |
套接字的类型必须是SOCK_RAW;
套接字的协议必须是IPPROTO_IP;
套接字必须同一个明确的本地接口建立绑定关系,也就是说不可将其绑定到INADDR_ANY。
1.2.4.12 SIO_RCVALL_MCAST
函数 | 输入 | 输出 | 说明 |
WSAIoctl | unsigned int | 无 | 接收网络上的所有多播数据包 |
套接字的类型必须是SOCK_RAW;
套接字的协议必须是IPPROTO_IGMP;
套接字必须同一个明确的本地接口建立绑定关系,也就是说不可将其绑定到INADDR_ANY。
1.2.4.13 SIO_RCVALL_IGMPMCAST
函数 | 输入 | 输出 | 说明 |
WSAIoctl | unsigned int | 无 | 接收网络上的所有IGMP数据包 |
套接字的类型必须是SOCK_RAW;
套接字的协议必须是IPPROTO_IGMP;
套接字必须同一个明确的本地接口建立绑定关系,也就是说不可将其绑定到INADDR_ANY。
1.2.4.14 SIO_ROUTING_INTERFACE_QUERY
函数 | 输入 | 输出 | 说明 |
WSAIoctl | SOCKADDR | SOCKADDR[ ] | 返回向指定地址发送数据的本地接口的地址。 |
1.2.4.15 SIO_ROUTING_INTERFACE_CHANGE
函数 | 输入 | 输出 | 说明 |
WSAIoctl | SOCKADDR | 无 | 与指定地址连接的本地接口发生改变后,发出通知 |
若套接字处在非阻塞模式,便会返回WSAEWOULDBLOCK错误。随后,应用程序可通过WSAEventSelect( )或WSAAsyncSelect(),等候FD_ROUTING_INTERFACE_CHANGE事件的发生。
输入SOCKADDR结构中指定的地址可以是一个具体的地址,亦可使用INADDR_ANY,表明发生任何路由更改,都发出通知。
1.2.4.16 SIO_ADDRESS_LIST_QUERY
函数 | 输入 | 输出 | 说明 |
WSAIoctl | 无 | SOCKET_ADDRESS_LIST | 返回与套接字协议家族相符的本地接口列表 |
typedefstruct _SOCKET_ADDRESS
{
LPSOCKADDR lpSockaddr;
INT iSockaddrLength;
}SOCKET_ADDRESS;
typedefstruct _SOCKET_ADDRESS_LIST
{
INT iAddressCount;
SOCKET_ADDRESS Address[1];
}SOCKET_ADDRESS_LIST;
其中,iAddressCount字段用于返回列表中地址结构的数量,而Address字段对应的是一个数组,包含了与协议家族相符的一系列地址。
1.2.4.17 SIO_ADDRESS_LIST_CHANGE
函数 | 输入 | 输出 | 说明 |
WSAIoctl | 无 | 无 | 套接字协议家族的本地接口列表发生变化, 发出通知 |
若套接字处于非阻塞模式,则返回WSAEWOULDBLOCK错误。随后,应用程序可利用WSAEventSelect( )或者WSAAsyncSelect(),等候FD_ADDRESS_LIST_CHANGE事件的发生。
1.2.4.18 SIO_GET_INTERFACE_LIST
函数 | 输入 | 输出 | 说明 |
WSAIoctl | 无 | INTERFACE_INFO[] | 返回本地接口列表 |
{
struct sockaddr Address;
struct sockaddr_in AddressIn;
struct sockaddr_in6_old AddressIn6;
}sockaddr_gen;
typedefstruct _INTERFACE_INFO
{
u_long iiFlags;
sockaddr_gen iiAddress;
sockaddr_gen iiBroadcastAddress;
sockaddr_gen iiNetmask;
}INTERFACE_INFO, FAR * LPINTERFACE_INFO;
iiFlags用于描述接口状态:
IFF_UP;IFF_BROADCAST;IFF_LOOPBACK;IFF_POINTTOPOINT;IFF_MULTICAST
iiAddress是接口的地址。
iiBroadcastAddress是接口对应的广播地址或点对点链路的对端地址。
iiNetmask是接口使用的网络掩码。
相关文章推荐
- Linux 网络编程 套接字选项
- 网络编程--套接字选项
- Windows的网络编程-之四-套接字模型
- Linux 之 网络编程之套接字选项
- 使用windows套接字进行网络编程
- 网络编程学习_套接字选项
- socket网络编程中常用的SO_KEEPALIVE套接字选项
- Linux网络编程--8. 套接字选项
- Linux网络编程之套接字选项设置 .
- Linux网络编程之套接字选项设置
- windows 网络编程 几种套接字模型
- 网络编程--套接字选项(一)
- 网络编程-常用的套接字选项
- (七)Linux网络编程--7. TCP/IP协议 8. 套接字选项
- 网络编程--套接字选项
- 我的网络编程学习之路——套接字选项
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 套接字选项的使用 (心跳检测、绑定地址复用)
- 网络编程——socket套接字的使用(一)
- [Linux网络编程学习笔记]套接字地址结构
- windows网络编程之重叠模型(OVERLAPPED I/O)基础知识