网络编程(基于winsocket)-- 常用函数介绍(二)
来源:互联网 发布:excel数据分析占比 编辑:程序博客网 时间:2024/06/13 11:55
此篇文章继续记录winsocket的常用函数
1、套接字选项
选项影响套接字的操作。获取和设置调节自选项的函数分别是getsockopt()和setsockopt()。
(1)setsockopt()
intWSAAPIsetsockopt(_In_ SOCKET s,_In_ int level,_In_ int optname,_In_reads_bytes_opt_(optlen) const char FAR * optval,_In_ int optlen);
参数s:指示套接字句柄;
参数level:指定此选项被定义在哪个级别,如SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP等;
参数optname:声明套接字选项的名称;
参数optval:指定一个缓冲区,存储所请求或定义的选项值;
参数optlen:指定参数optval所指的缓冲区的大小
如果函数成功,则返回0,否则返回SOCKET_ERROR。
OSI网络分层结构对应参数level的不同级别:
应用层:参数level设置为SOL_SOCKET,是对套接字自身的一些参数的配置;
传输层:协议为TCP、UDP,参数level设置为IPPROTO_TCP、IPPROTO_UDP;
网络层:参数level设置为IPPROTO_IP。
BOOL bReuseaddr = TRUE;setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&bReuseaddr, sizeof(BOOL));
2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历 TIME_WAIT的过程:
BOOL bDontLinger = FALSE;setsockopt(s, SOL_SOCKET, SO_DONTLINGER, (const char*)&bDontLinger, sizeof(BOOL));
3.在send(),recv()过程中有时由于网络状况等原因,发收不能预期进行,而设置收发时限:
int nNetTimeout = 1000;//1秒 //发送时限 setsockopt(socket,SOL_S0CKET, SO_SNDTIMEO,(char *)&nNetTimeout, sizeof(int));//接收时限 setsockopt(socket,SOL_S0CKET, SO_RCVTIMEO,(char *)&nNetTimeout, sizeof(int));
4.在send()的时候,返回的是实际发送出去的字节(同步)或发送到socket缓冲区的字节 (异步);系统默认的状态发送和接收一次为8688字节(约为8.5K);
/ 接收缓冲区int nRecvBuf = 32 * 1024;//设置为32K setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));//发送缓冲区 int nSendBuf=32*1024;//设置为32K setsockopt(s, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int));
5. 如果在发送数据的时,希望不经历由系统缓冲区到socket缓冲区的拷贝而影响程序的性能:
int nZero = 0;setsockopt(socket,SOL_S0CKET, SO_SNDBUF,(char *)&nZero, sizeof(nZero));
6.同上在recv()完成上述功能(默认情况是将socket缓冲区的内容拷贝到系统缓冲区):
int nZero = 0;setsockopt(socket,SOL_S0CKET, SO_RCVBUF,(char *)&nZero, sizeof(int));
7.一般在发送UDP数据报的时候,希望该socket发送的数据具有广播特性:
BOOL bBroadcast=TRUE; setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL));
8.在client连接服务器过程中,如果处于非阻塞模式下的socket在connect()的过程中可以设置connect()延时,直到accpet()被呼叫(本函数设置只有在非阻塞的过程中有显著的作用,在阻塞的函数调用中作用不大)
BOOL bConditionalAccept = TRUE;setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (const char*)&bConditionalAccept, sizeof(BOOL));
9.如果在发送数据的过程中(send()没有完成,还有数据没发送)而调用了closesocket(),以前我们一般采取的措施是"从容关闭"shutdown(s,SD_BOTH),但是数据是肯定丢失了,如何设置让程序满足具体应用的要求(即让没发完的数据发送出去后在关闭socket
struct linger{u_short l_onoff;u_short l_linger;};linger m_sLinger;m_sLinger.l_onoff = 1;//(在closesocket()调用,但是还有数据没发送完毕的时候容许逗留) 如果m_sLinger.l_onoff=0;则功能和2.)作用相同; m_sLinger.l_linger = 5; //(容许逗留的时间为5秒) setsockopt(s, SOL_SOCKET, SO_LINGER, (const char*)&m_sLinger, sizeof(linger));
(2)getsockopt()
intWSAAPIgetsockopt(_In_ SOCKET s,_In_ int level,_In_ int optname,_Out_writes_bytes_(*optlen) char FAR * optval,_Inout_ int FAR * optlen);
此函数用于取得socket套接字的操作选项值,例:
int nNetTimeout;//时间//发送时限 getsockopt(socket,SOL_S0CKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int)); //函数会在nNetTimeout返回设置的时间
2、I/O控制命令
I/O控制命令(缩写为ioctl)用来控制套接字上I/O的行为,也可以用来获取套接字上未决的I/O信息。向套接字发送I/O控制命令的函数有两个:winsock1.1:ioctlsocket();winsock2:WSAIoctl()。
(1)ioctlsocket()
ioctlsocket()函数可以控制套接字的I/O模式
intWSAAPIioctlsocket( _In_ SOCKET s, _In_ long cmd, _Inout_ u_long FAR * argp );参数s:是一个套接字句柄
参数cmd:指示在套接字上要执行的命令
参数argp:指向套接字参数的指针
(2)WSAIoctl()
此函数是winsock2新引进的I/O控制命令函数,它增加了一些输入参数,同时还增加了一些输入参数用来从调用中返回数据。另外,该函数还可以使用重叠I/O。
intWSAAPIWSAIoctl( _In_ SOCKET s, _In_ DWORD dwIoControlCode, _In_reads_bytes_opt_(cbInBuffer) LPVOID lpvInBuffer, _In_ DWORD cbInBuffer, _Out_writes_bytes_to_opt_(cbOutBuffer, *lpcbBytesReturned) LPVOID lpvOutBuffer, _In_ DWORD cbOutBuffer, _Out_ LPDWORD lpcbBytesReturned, _Inout_opt_ LPWSAOVERLAPPED lpOverlapped, _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
参数dwIoControlCode:描述将进行的操作控制代码,在设置接收全部选项时使用SIO_RCVALL
参数lpvInBuffer:指向输入缓冲区的地址
参数cbInBuffer:指向输入缓冲区的大小
参数lpvOutBuffer:指向输出缓冲区的地址
参数cbOutBuffer:指向输出缓冲区的大小
参数IpcbBytesReturned:是一个输出参数,返回输出实际字节数的地址
参数IpOverlapped:指向WSAOVERLAPPED的结构的地址
参数IpCompletionRoutine:指向操作结束后调用的例程指针
注:最后两个参数在重叠I/O时才会使用。
示例:
u_long mode = 0;ioctlsocket(s, FIONBIO, &mode); //控制为阻塞方式 u_long mode = 1;ioctlsocket(s, FIONBIO, &mode); //控制为非阻塞方式
- 网络编程(基于winsocket)-- 常用函数介绍(二)
- 网络编程(基于winsocket)-- 常用函数介绍(一)
- 网络编程(基于WinSocket)---基础知识
- 网络编程(基于winsocket)-- I/O操作模型介绍--I/0复用模型
- (二)Linux网络编程--初等网络函数介绍(TCP)
- 基于VB2008的winsocket控件网络编程
- 网络-WinSocket-socket编程
- 基于TCP网络编程常用函数
- postgis常用函数介绍(二)
- 网络编程(整理)常用函数
- 【网络编程】之一、初识WinSocket
- 【网络编程】之一、初识WinSocket
- 网络编程1-初探winSocket
- 网络编程函数笔记(二)
- Unix网络编程(二)套接字地址结构常用函数
- 利用WinSocket发数据(二)
- winsocket编程几种模式(1)
- winsocket编程几种模式(2)
- JZOJ 1322. 硬币游戏
- xADC
- 用Wireshark保存RTP的负载码流
- POJ 3254 Corn Fields 状压dp入门
- Servlet基础笔记_17-07-05
- 网络编程(基于winsocket)-- 常用函数介绍(二)
- Scala练习-哈希查找
- 变量-常量
- daemon 进程如何打日志到控制台?
- 葵花宝典 十四 标签库
- 剑指offer | 训练题59:把二叉树打印成多行
- 多线程程序设计之创建线程(Windows下C++实现)
- java实现定时任务的方法
- 字符串 leetcode 387. First Unique Character in a String