首页 > 其他分享 >UDP --02--UDP广播数据

UDP --02--UDP广播数据

时间:2022-11-11 22:36:57浏览次数:62  
标签:02 选项 UDP -- TCP Windows SO 接字 IAS


设计模型

UDP --02--UDP广播数据_数据


局域网UDP广播数据端UdpBroadCast.cpp 

#include <tchar.h> // _T宏
#include <stdio.h>// printf sprintf

#include <iostream>// cout fstream
using namespace std;

// windows socket
#include <winsock.h>
#pragma comment (lib,"ws2_32.lib")

bool initSocketLib();

void main()
{
SOCKET sock; //socket套接字
char szMsg[] = "this is a UDP test package";//被发送的字段

// 1.启动SOCKET库,版本为2.0
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( 0 != err ) {
cout<<"Socket2.0初始化失败,Exit!";
return;
}
if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0 ) { // 检查Socket库的版本是否为2.0
WSACleanup( );
return;
}

// 2.创建socket
sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_IP/*虚拟IP*/);
if (INVALID_SOCKET == sock ) {
cout<<"Socket 创建失败,Exit!";
return;
}

// 3.设置该套接字为广播类型,
bool opt = true;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST/*广播*/, reinterpret_cast<char FAR *>(&opt), sizeof(opt));

// 4.设置发往的地址
sockaddr_in addrto;
memset(&addrto,0,sizeof(addrto));
addrto.sin_family = AF_INET; // 地址类型为internetwork
addrto.sin_addr.s_addr = INADDR_BROADCAST; // 设置ip为广播地址
addrto.sin_port = htons(7861); // 端口号为7861
int nlen=sizeof(addrto);
unsigned int uIndex = 1;

while(true) {
Sleep(1000);

//向广播地址发送消息
if( sendto(sock, szMsg, strlen(szMsg), 0, (sockaddr*)&addrto,nlen)== SOCKET_ERROR ) {
cout<<WSAGetLastError()<<endl;
}
else {
cout<<uIndex++<<":an UDP package is sended."<<endl;
}
}

if (!closesocket(sock)) { // 关闭套接字
WSAGetLastError();
return;
}
if (!WSACleanup()) { // 关闭Socket库
WSAGetLastError();
return;
}

return;
}

bool initSocketLib()
{
WSADATA Data;

//初始化windows Socket Dll
int status = WSAStartup(MAKEWORD(1,1),&Data);
if (0!=status)
{
printf(_T("初始化失败\n"));
return false;
}

return true;
}



局域网UDP接收广播数据端Receive.cpp

#include <tchar.h> // _T宏
#include <stdio.h>// printf sprintf

#include <iostream>// cout fstream
using namespace std;

// windows socket
#include <winsock.h>
#pragma comment (lib,"ws2_32.lib")

bool initSocketLib();

void main()
{
if(!initSocketLib())
return;

// 初始化本地客户端套接字
SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(serSocket == INVALID_SOCKET)
{
printf("socket error !");
return ;
}

// "本地"的服务端地址映射(IP:port)
sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(7861);
serAddr.sin_addr.S_un.S_addr = inet_addr("192.168.0.53");// 因为这是远程机器,客户端也不在本机上,所以绑定实际的物理地址

if(bind(serSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{
printf("bind error !");
closesocket(serSocket);
return ;
}

sockaddr_in remoteAddr;
int nAddrLen = sizeof(remoteAddr);
while (true)
{
char recvData[255];
int ret = recvfrom(serSocket, recvData, 255, 0, (sockaddr *)&remoteAddr, &nAddrLen);
if (ret > 0)
{
recvData[ret] = 0x00;
printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));
printf(recvData);
}

//char * sendData = "一个来自服务端的UDP数据包\n";
//sendto(serSocket, sendData, strlen(sendData), 0, (sockaddr *)&remoteAddr, nAddrLen);

}

closesocket(serSocket);
WSACleanup();
return ;

}

bool initSocketLib()
{
WSADATA Data;

//初始化windows Socket Dll
int status = WSAStartup(MAKEWORD(1,1),&Data);
if (0!=status)
{
printf(_T("初始化失败\n"));
return false;
}

return true;
}


setsockopt函数




该 setsockopt的功能设置一个套接字选项。

句法



C ++





int setsockopt(
_In_ SOCKET s,
_In_ int level,
_In_ int optname,
_In_ const char * optval,
_In_ int optlen
);



参数


s [in]


标识套接字的描述符。

水平 [in]


定义选项的级别(例如,SOL_SOCKET)。

optname [in]


要为其设置值的套接字选项(例如,SO_BROADCAST)。所述OPTNAME参数必须在规定的范围内所定义的套接字选项级别,或行为是未定义的。

optval [in]


指向缓冲区的指针,其中指定了所请求的选项的值。

optlen [in]


optval参数指向的缓冲区的大小(以字节为单位)。

返回值

如果没有发生错误,则 setsockopt将返回零。否则返回值SOCKET_ERROR,并通过调用​WSAGetLastError​来检索特定的错误代码 。




错误代码

含义

WSANOTINITIALISED

在使用此功能之前,必须发生成功的 ​WSAStartup​调用。

WSAENETDOWN

网络子系统失败。

WSAEFAULT

optval参数指向的缓冲区不在进程地址空间的有效部分或 optlen参数太小。

WSAEINPROGRESS

正在进行阻止Windows Sockets 1.1呼叫,或者服务提供商仍在处理回调函数。

WSAEINVAL

电平的参数是无效的,或者在缓冲器中的信息指向的optval的参数是无效的。

WSAENETRESET

设置​SO_KEEPALIVE​时,连接已超时。

WSAENOPROTOOPT

该选项对于指定的提供程序或套接字是未知的或不受支持的(请参阅SO_GROUP_PRIORITY限制)。

WSAENOTCONN

SO_KEEPALIVE​设置后,连接已被重置。

WSAENOTSOCK

描述符不是套接字。


 


错误代码

含义

WSANOTINITIALISED

在使用此功能之前,必须发生成功的 ​WSAStartup​调用。

WSAENETDOWN

网络子系统失败。

WSAEFAULT

optval参数指向的缓冲区不在进程地址空间的有效部分或 optlen参数太小。

WSAEINPROGRESS

正在进行阻止Windows Sockets 1.1呼叫,或者服务提供商仍在处理回调函数。

WSAEINVAL

电平的参数是无效的,或者在缓冲器中的信息指向的optval的参数是无效的。

WSAENETRESET

设置​SO_KEEPALIVE​时,连接已超时。

WSAENOPROTOOPT

该选项对于指定的提供程序或套接字是未知的或不受支持的(请参阅SO_GROUP_PRIORITY限制)。

WSAENOTCONN

SO_KEEPALIVE​设置后,连接已被重置。

WSAENOTSOCK

描述符不是套接字。


 

备注





备注

的 setsockopt的函数设置用于与任何类型的插座,在任何状态相关联的套接字选项的当前值。虽然选项可以存在于多个协议级别,但它们始终位于最上层的套接字级别。选项影响套接字操作,例如在正常数据流中是否接收到加急数据(例如,OOB数据),以及是否可以在套接字上发送广播消息。


注意:   如果  setsockopt的功能是之前调用  ​绑定​功能,TCP / IP选项将不会被直到使用TCP / IP检查  结合进行。在这种情况下,  setsockopt函数调用将始终成功,但由于早期的 setsockopt调用失败,  绑定函数调用可能会 失败。


 


注意   如果一个套接字被打开,将进行一个  setsockopt调用,然后进行一个  ​sendto​​调用,Windows Sockets执行一个隐式的  ​​绑定​函数调用。


 


有两种类型的套接字选项:启用或禁用特性或行为的布尔选项,以及需要整数值或结构的选项。要启用布尔选项,optval参数指向非零整数。要禁用选项optval指向等于零的整数。对于布尔选项,optlen参数应该等于​​sizeof(int)​​。对于其他选项,optval指向包含该选项所需值的整数或结构,optlen是整数或结构的长度。

下表列出了setsockopt函数支持的一些常用选项。“类型”列标识由optval参数寻址的数据类型。“说明”列提供了有关套接字选项的一些基本信息。有关套接字选项和更详细信息(例如默认值)的更完整列表,请参阅“ ​套接字选项”​下的详细主题。

level = SOL_SOCKET



类型

描述

SO_BROADCAST

BOOL

配置发送广播数据的套接字。

SO_CONDITIONAL_ACCEPT

BOOL

允许传入连接被应用程序接受或拒绝,而不是协议栈。

SO_DEBUG

BOOL

启用调试输出。Microsoft提供商目前不输出任何调试信息。

SO_DONTLINGER

BOOL

不阻止关闭等待未发送的数据。设置此选项等同于将l_onoff设置为零时设置SO_LINGER 。

SO_DONTROUTE

BOOL

设置传出数据是否应在套接字绑定的接口上发送,而不是在某个其他接口上发送。ATM套接字不支持此选项(导致错误)。

SO_GROUP_PRIORITY

INT

保留。

SO_KEEPALIVE

BOOL

允许为套接字连接发送保持活动数据包。ATM套接字不支持(导致错误)。

SO_LINGER

萦绕

如果不存在数据,则关闭。

SO_OOBINLINE

BOOL

表示外部数据应与常规数据一致返回。此选项仅适用于支持带外数据的面向连接的协议。有关此主题的讨论,请参阅无 ​​协议独立的带外数据​​。

SO_RCVBUF

INT

指定保留接收的每个套接字缓冲区总数。

SO_REUSEADDR

BOOL

允许套接字绑定到已经在使用的地址。有关更多信息,请参阅 ​绑定​。不适用于ATM插座。

​SO_EXCLUSIVEADDRUSE​

BOOL

使套接字被绑定以进行独占访问。不需要管理权限。

SO_RCVTIMEO

DWORD

设置阻止接收呼叫的超时(以毫秒为单位)。

SO_SNDBUF

INT

指定为发送预留的每个套接字缓冲区总数。

SO_SNDTIMEO

DWORD

阻塞发送呼叫的超时(以毫秒为单位)。

SO_UPDATE_ACCEPT_CONTEXT

INT

使用监听套接字的上下文更新接受套接字。

PVD_CONFIG

服务提供者依赖

此对象存储与套接字s关联的服务提供商的配置信息。该数据结构的确切格式是特定于服务提供商。


 

有关level = SOL_SOCKET的套接字选项的更完整和详细的信息,请参阅​SOL_SOCKET套接字选项​。

level = IPPROTO_TCP



类型

描述

TCP_NODELAY

BOOL

此套接字选项包括与Windows Sockets 1.1的向后兼容性


 

有关level = IPPROTO_TCP的套接字选项的更完整和详细的信息,请参阅​IPPROTO_TCP套接字选项​。

level = NSPROTO_IPX



类型

描述

IPX_PTYPE

INT

设置IPX包类型。

IPX_FILTERPTYPE

INT

设置接收过滤器包类型

IPX_STOPFILTERPTYPE

INT

停止过滤使用IPX_FILTERTYPE设置的过滤器类型

IPX_DSTYPE

INT

在发送的每个数据包上设置SPX头中数据流字段的值。

IPX_EXTENDED_ADDRESS

BOOL

设置是否启用扩展寻址。

IPX_RECVHDR

BOOL

设置协议头是否在所有接收头上发送。

IPX_RECEIVE_BROADCAST

BOOL

表示广播报文很可能在套接字上。默认设置为TRUE。不使用广播的应用程序应将其设置为FALSE以获得更好的系统性能。

IPX_IMMEDIATESPXACK

BOOL

指示SPX连接在发送ACK之前不会延迟。没有来回流量的应用程序应将此设置为TRUE,以提高性能。


 

有关level = NSPROTO_IPX的套接字选项的更完整和详细的信息,请参阅​NSPROTO_IPX套接字选项​。

setsockopt不支持的BSD选项 如下表所示。



类型

描述

SO_ACCEPTCONN

BOOL

返回套接字是否处于侦听模式。此选项仅适用于面向连接的协议。该套接字选项不支持该设置。

SO_RCVLOWAT

INT

包括BSD UNIX的套接字选项,用于向后兼容。此选项设置套接字输入操作要处理的最小字节数。

SO_SNDLOWAT

INT

包括BSD UNIX的套接字选项,用于向后兼容。此选项设置套接字输出操作要处理的最小字节数。

SO_TYPE

INT

返回给定套接字的套接字类型(SOCK_STREAM或SOCK_DGRAM,例如套接字类型的设置不支持此套接字选项。


 


SO_CONDITIONAL_ACCEPT

将此套接字选项设置为TRUE会延迟连接的确认,直到调用​WSAAccept​条件函数为止 。如果为FALSE,则在调用条件功能之前可以接受连接,但如果条件功能拒绝该呼叫,则连接将被断开。在调用​listen​函数之前必须设置此选项 ,否则返回WSAEINVAL。SO_CONDITIONAL_ACCEPT仅支持TCP和ATM。

默认情况下,TCP将SO_CONDITIONAL_ACCEPT设置为FALSE,因此默认情况下,将在​WSAAccept​条件函数被调用之前接受连接 。当设置为TRUE时,必须在TCP连接超时之内进行条件决定。CF_DEFER连接仍然会超时。

默认情况下,ATM将SO_CONDITIONAL_ACCEPT设置为TRUE

SO_DEBUG

如果应用程序设置了SO_DEBUG选项,Windows Sockets服务提供商将被鼓励(但不是必需)提供输出调试信息。用于生成调试信息及其形式的机制超出了本文档的范围。

SO_GROUP_PRIORITY

保留以备将来使用套接字组。组优先级表示指定套接字相对于套接字组内其他套接字的相对优先级。值是非负整数,零对应于最高优先级。优先级值代表底层服务提供商关于如何分配潜在稀缺资源的提示。例如,当两个或更多个套接字都准备好传输数据时,最高优先级套接字(SO_GROUP_PRIORITY的最低值)应首先进行处理,其余的根据其相对优先级依次进行服务。

SO_KEEPALIVE


应用程序可以通过打开SO_KEEPALIVE套接字选项来请求TCP / IP提供商启用TCP连接上的保持活动数据包。Windows Sockets提供程序不需要支持使用keep-alives。如果是这样,精确的语义是实现特定的,但应符合关于​​IETF网站上​​提供的RFC 1122中规定的Internet主机 - 通信层要求的第4.2.3.6节。(此资源只能用英文提供)

如果由于保持活动而导致连接丢失,则错误代码 ​​WSAENETRESET​​​将返回到套接字上正在进行的任何调用,并且随后的任何调用将随​​WSAENOTCONN​​失败。

如果对具有​SO_KEEPALIVE​​的TCP套接字启用了保持活动,则默认TCP设置用于保持活动超时和间隔,除非通过使用​SIO_KEEPALIVE_VALS​​选项调用​WSAIoctl​函数 来更改这些值。

SO_LINGER

SO_LINGER选项控制未连接的数据在套接字上排队并执行​closesocket​时所采取的 操作。见 字关闭了,其中的SO_LINGER设置影响语义的方式描述 关闭套接字。应用程序通过创建​LERER​结构(由optval参数指向)来设置所需的行为 ,这些成员使用这些成员l_onoffl_linger进行适当的设置。

SO_REUSEADDR

默认情况下,不能绑定一个套接字(请参阅 ​bind​)到已经在使用的本地地址。然而,有时,可能需要以这种方式重用地址。由于每个连接都由本地和远程地址的组合唯一标识,所以只要远程地址不同,就将两个套接字绑定到相同的本地地址就没有问题。要通知Windows Sockets提供程序,因为所需的地址已被另一个套接字使用,应该不会禁止套接字上的 绑定,所以应用程序应该在发布绑定之前为套接字设置SO_REUSEADDR套接字选项 。该选项仅在绑定时解释 。 在不绑定到现有地址的套接字上设置该选项是不必要和无害的。绑定后设置或重置该选项对此或任何其他套接字没有影响。

SO_RCVBUF和SO_SNDBUF

当Windows Sockets实现支持SO_RCVBUF和SO_SNDBUF选项时,应用程序可以请求不同的缓冲区大小(更大或更小)。即使实施没有提供所请求的总额,对setsockopt的调用 也可以成功。应用程序必须使用相同的选项调用 ​getsockopt​来检查实际提供的缓冲区大小。

SO_RCVTIMEO和SO_SNDTIMEO

当使用 ​recv​功能时,如果在SO_RCVTIMEO指定的时间段内没有数据到达,则 recv功能完成。在Windows 2000之前的Windows版本中,随后使用​​WSAETIMEDOUT​​,接收到的任何数据都将失败。在Windows 2000及更高版本中,如果在SO_RCVTIMEO 指定的时间内没有数据到达,则 recv函数返回WSAETIMEDOUT,如果接收到数据,则 recv返回SUCCESS。

如果发送或接收操作在套接字上超时,套接字状态是不确定的,不应该使用; 在这种状态下的TCP插座有可能导致数据丢失,因为操作可以在操作完成的同一时间被取消。

PVD_CONFIG

此对象存储与s参数中指定的套接字相关联的服务提供商的配置信息。这种数据结构的确切格式是每个服务提供商所特有的。

TCP_NODELAY

TCP_NODELAY选项特定于TCP / IP服务提供商。如果启用TCP_NODELAY选项(反之亦然),Nagle算法将被禁用。该过程涉及当有未确认的数据已经在飞行中或缓冲发送数据时缓冲发送数据,直到可以发送全尺寸数据包。强烈建议TCP / IP服务提供商默认启用Nagle算法,对于绝大多数应用协议,Nagle算法可以提供显着的性能增强。但是,对于某些应用程序,该算法可能会阻碍性能,TCP_NODELAY可用于将其关闭。这些是发送许多小消息的应用程序,并且维护消息之间的时间延迟。

注意   当发出阻止Winsock调用(如 setsockopt)时,Winsock可能需要等待网络事件才能完成调用。在这种情况下,Winsock会执行一个可警告的等待,这可以通过在同一线程上安排的异步过程调用(APC)中断。在APC中发出另一个阻塞Winsock调用,该过程会在同一个线程上中断正在进行的阻塞Winsock调用,这将导致未定义的行为,绝对不能由Winsock客户端尝试。


 


示例代码

以下示例演示了setsockopt函数。


C ++





#ifndef UNICODE 
#define UNICODE
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <
winsock2.h>
#include < Ws2tcpip.h> #include <stdio.h> //链接ws2_32.lib
#pragma comment(lib,“Ws2_32.lib”)int main()
{ // ------------------------------------- - //声明变量
WSADATA wsaData;
SOCKET ListenSocket;
sockaddr_in服务; int iResult = 0;
BOOL bOptVal = FALSE; int bOptLen = sizeof(BOOL); int iOptVal = 0;
int iOptLen = sizeof(int); // --------------------------------------- //初始化Winsock
iResult = WSAStartup(MAKEWORD (2,2),&wsaData); if(iResult!= NO_ERROR){
wprintf(L “Error at WSAStartup()\ n”);
返回 1;
} // --------------------------------------- //创建一个监听套接字
ListenSocket =套接字(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(ListenSocket == INVALID_SOCKET){
wprintf(L “socket function failed with error:%u \ n”,WSAGetLastError());
WSACleanup(); 返回 1;
} // --------------------------------------- //将套接字绑定到本地IP地址//和端口27015
hostent * thisHost; char * ip;
u_short端口
端口= 27015;
thisHost = gethostbyname(“”);
ip = inet_ntoa(*(struct in_addr *)* thisHost-> h_addr_list);
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);
iResult = bind(ListenSocket,(SOCKADDR *)&service,sizeof(service));
if(iResult == SOCKET_ERROR){
wprintf(L “bind failed with error%u \ n”,WSAGetLastError());
关闭套接字(ListenSocket);
WSACleanup(); 返回 1;
} // --------------------------------------- //初始化变量并调用setsockopt。// SO_KEEPALIVE参数是一个套接字选项//使套接字在会话上发送keepalive消息//。SO_KEEPALIVE套接字选项//需要将一个布尔值传递给// setsockopt函数。如果为TRUE,则套接字//配置为发送keepalive消息,如果FALSE //套接字配置为不发送keepalive消息。//这段代码通过使用getsockopt函数检查套接字上的SO_KEEPALIVE的状态来测试setsockopt函数// 。
bOptVal = TRUE;
iResult = getsockopt(ListenSocket,SOL_SOCKET,SO_KEEPALIVE,(char *)&iOptVal,&iOptLen);
if(iResult == SOCKET_ERROR){
wprintf(L “getsockopt for SO_KEEPALIVE failed with error:%u \ n”,WSAGetLastError());
} else
wprintf(L “SO_KEEPALIVE Value:%ld \ n”,iOptVal);
iResult = setsockopt(ListenSocket,SOL_SOCKET,SO_KEEPALIVE,(char *)&bOptVal,bOptLen);
if(iResult == SOCKET_ERROR){
wprintf(L “setsockopt for SO_KEEPALIVE failed with error:%u \ n”,WSAGetLastError());
} else
wprintf(L “Set SO_KEEPALIVE:ON \ n”);
iResult = getsockopt(ListenSocket,SOL_SOCKET,SO_KEEPALIVE,(char *)&iOptVal,&iOptLen);
if(iResult == SOCKET_ERROR){
wprintf(L “getsockopt for SO_KEEPALIVE failed with error:%u \ n”,WSAGetLastError());
} else
wprintf(L “SO_KEEPALIVE Value:%ld \ n”,iOptVal);
关闭套接字(ListenSocket);
WSACleanup(); 返回 0;
}


IrDA插座注意事项

在使用IrDA的Windows套接字开发应用程序时,请注意以下事项:

  • 必须明确地包含Af_irda.h头文件。
  • IrDA提供以下套接字选项:


类型

含义

IRLMP_IAS_SET

* IAS_SET

设置IAS属性

IRLMP_IAS_SET套接字选项使应用程序可以在本地IAS中设置单个类的单个属性。应用程序指定要设置的类,属性和属性类型。应用程序预期为传递的参数分配必要大小的缓冲区。

IrDA提供了一个存储基于IrDA的信息的IAS数据库。通过Windows Sockets 2接口可以访问对IAS数据库的访问,但这种访问通常不被应用程序使用,并且主要用于支持与不符合Windows Sockets 2 IrDA约定的非Windows设备的连接。

以下结构IAS_SET与IRLMP_IAS_SET setsockopt选项一起用于管理本地IAS数据库:


C ++





// #include <Af_irda.h>为此struct 

typedef struct _IAS_SET {
u_char irdaClassName [IAS_MAX_CLASSNAME]; char irdaAttribName [IAS_MAX_ATTRIBNAME];
u_long irdaAttribType; 工会
{
LONG irdaAttribInt; struct
{
u_long Len;
u_char OctetSeq [IAS_MAX_OCTET_STRING];
irdaAttribOctetSeq; struct
{
u_long Len;
u_long CharSet;
u_char UsrStr [IAS_MAX_USER_STRING];
irdaAttribUsrStr;
irdaAttribute;


以下结构IAS_QUERY与IRLMP_IAS_QUERY setsockopt选项一起用于查询对等体的IAS数据库:


C ++





// #include <Af_irda.h>为此struct 

typedef struct _WINDOWS_IAS_QUERY {
u_char irdaDeviceID [4]; char irdaClassName [IAS_MAX_CLASSNAME];
char irdaAttribName [IAS_MAX_ATTRIBNAME];
u_long irdaAttribType; 工会
{
LONG irdaAttribInt; struct
{
u_long Len;
u_char OctetSeq [IAS_MAX_OCTET_STRING];
irdaAttribOctetSeq; struct
{
u_long Len;
u_long CharSet;
u_char UsrStr [IAS_MAX_USER_STRING];
irdaAttribUsrStr;
irdaAttribute;
} IAS_QUERY,* PIAS_QUERY,FAR * LPIASQUERY;


许多SO_级套接字选项对IrDA无效。只有SO_LINGER被特别支持。

Windows Phone 8: Windows Phone 8及更高版本上的Windows Phone Store应用程序支持此功能。

Windows 8.1Windows Server 2012 R2:Windows 8.1,Windows Server 2012 R2和更高版本上的Windows Store应用程序支持此功能。

要求


最低支持客户端

Windows 8.1,Windows Vista [桌面应用程序| Windows Store应用程序]

最低支持服务器

Windows Server 2003 [桌面应用程序| Windows Store应用程序]

最低支持的手机

Windows Phone 8


Winsock2.h

图书馆

WS2_32.LIB

DLL

WS2_32.DLL


也可以看看


捆绑

用getsockopt

ioctlsocket

IPPROTO_IP套接字选项

IPPROTO_IPV6套接字选项

IPPROTO_RM套接字选项

IPPROTO_TCP套接字选项

IPPROTO_UDP套接字选项

NSPROTO_IPX套接字选项

插座

套接字选项

SOL_APPLETALK套接字选项

SOL_IRLMP套接字选项

SOL_SOCKET套接字选项

​Winsock功能​

WSAAsyncSelect

WSAEventSelect

的WSAIoctl


错误代码

含义

WSANOTINITIALISED

在使用此功能之前,必须发生成功的 ​WSAStartup​调用。

WSAENETDOWN

网络子系统失败。

WSAEFAULT

optval参数指向的缓冲区不在进程地址空间的有效部分或 optlen参数太小。

WSAEINPROGRESS

正在进行阻止Windows Sockets 1.1呼叫,或者服务提供商仍在处理回调函数。

WSAEINVAL

电平的参数是无效的,或者在缓冲器中的信息指向的optval的参数是无效的。

WSAENETRESET

设置​SO_KEEPALIVE​时,连接已超时。

WSAENOPROTOOPT

该选项对于指定的提供程序或套接字是未知的或不受支持的(请参阅SO_GROUP_PRIORITY限制)。

WSAENOTCONN

SO_KEEPALIVE​设置后,连接已被重置。

WSAENOTSOCK

描述符不是套接字。



 

备注


备注

的 setsockopt的函数设置用于与任何类型的插座,在任何状态相关联的套接字选项的当前值。虽然选项可以存在于多个协议级别,但它们始终位于最上层的套接字级别。选项影响套接字操作,例如在正常数据流中是否接收到加急数据(例如,OOB数据),以及是否可以在套接字上发送广播消息。



注意:   如果  setsockopt的功能是之前调用  ​绑定​功能,TCP / IP选项将不会被直到使用TCP / IP检查  结合进行。在这种情况下,  setsockopt函数调用将始终成功,但由于早期的 setsockopt调用失败,  绑定函数调用可能会 失败。



 



注意   如果一个套接字被打开,将进行一个  setsockopt调用,然后进行一个  ​sendto​​调用,Windows Sockets执行一个隐式的  ​​绑定​函数调用。



 



有两种类型的套接字选项:启用或禁用特性或行为的布尔选项,以及需要整数值或结构的选项。要启用布尔选项,optval参数指向非零整数。要禁用选项optval指向等于零的整数。对于布尔选项,optlen参数应该等于​​sizeof(int)​​。对于其他选项,optval指向包含该选项所需值的整数或结构,optlen是整数或结构的长度。

下表列出了setsockopt函数支持的一些常用选项。“类型”列标识由optval参数寻址的数据类型。“说明”列提供了有关套接字选项的一些基本信息。有关套接字选项和更详细信息(例如默认值)的更完整列表,请参阅“ ​套接字选项”​下的详细主题。

level = SOL_SOCKET




类型

描述

SO_BROADCAST

BOOL

配置发送广播数据的套接字。

SO_CONDITIONAL_ACCEPT

BOOL

允许传入连接被应用程序接受或拒绝,而不是协议栈。

SO_DEBUG

BOOL

启用调试输出。Microsoft提供商目前不输出任何调试信息。

SO_DONTLINGER

BOOL

不阻止关闭等待未发送的数据。设置此选项等同于将l_onoff设置为零时设置SO_LINGER 。

SO_DONTROUTE

BOOL

设置传出数据是否应在套接字绑定的接口上发送,而不是在某个其他接口上发送。ATM套接字不支持此选项(导致错误)。

SO_GROUP_PRIORITY

INT

保留。

SO_KEEPALIVE

BOOL

允许为套接字连接发送保持活动数据包。ATM套接字不支持(导致错误)。

SO_LINGER

萦绕

如果不存在数据,则关闭。

SO_OOBINLINE

BOOL

表示外部数据应与常规数据一致返回。此选项仅适用于支持带外数据的面向连接的协议。有关此主题的讨论,请参阅无 ​​协议独立的带外数据​​。

SO_RCVBUF

INT

指定保留接收的每个套接字缓冲区总数。

SO_REUSEADDR

BOOL

允许套接字绑定到已经在使用的地址。有关更多信息,请参阅 ​绑定​。不适用于ATM插座。

​SO_EXCLUSIVEADDRUSE​

BOOL

使套接字被绑定以进行独占访问。不需要管理权限。

SO_RCVTIMEO

DWORD

设置阻止接收呼叫的超时(以毫秒为单位)。

SO_SNDBUF

INT

指定为发送预留的每个套接字缓冲区总数。

SO_SNDTIMEO

DWORD

阻塞发送呼叫的超时(以毫秒为单位)。

SO_UPDATE_ACCEPT_CONTEXT

INT

使用监听套接字的上下文更新接受套接字。

PVD_CONFIG

服务提供者依赖

此对象存储与套接字s关联的服务提供商的配置信息。该数据结构的确切格式是特定于服务提供商。



 

有关level = SOL_SOCKET的套接字选项的更完整和详细的信息,请参阅​SOL_SOCKET套接字选项​。

level = IPPROTO_TCP




类型

描述

TCP_NODELAY

BOOL

此套接字选项包括与Windows Sockets 1.1的向后兼容性



 

有关level = IPPROTO_TCP的套接字选项的更完整和详细的信息,请参阅​IPPROTO_TCP套接字选项​。

level = NSPROTO_IPX




类型

描述

IPX_PTYPE

INT

设置IPX包类型。

IPX_FILTERPTYPE

INT

设置接收过滤器包类型

IPX_STOPFILTERPTYPE

INT

停止过滤使用IPX_FILTERTYPE设置的过滤器类型

IPX_DSTYPE

INT

在发送的每个数据包上设置SPX头中数据流字段的值。

IPX_EXTENDED_ADDRESS

BOOL

设置是否启用扩展寻址。

IPX_RECVHDR

BOOL

设置协议头是否在所有接收头上发送。

IPX_RECEIVE_BROADCAST

BOOL

表示广播报文很可能在套接字上。默认设置为TRUE。不使用广播的应用程序应将其设置为FALSE以获得更好的系统性能。

IPX_IMMEDIATESPXACK

BOOL

指示SPX连接在发送ACK之前不会延迟。没有来回流量的应用程序应将此设置为TRUE,以提高性能。



 

有关level = NSPROTO_IPX的套接字选项的更完整和详细的信息,请参阅​NSPROTO_IPX套接字选项​。

setsockopt不支持的BSD选项 如下表所示。




类型

描述

SO_ACCEPTCONN

BOOL

返回套接字是否处于侦听模式。此选项仅适用于面向连接的协议。该套接字选项不支持该设置。

SO_RCVLOWAT

INT

包括BSD UNIX的套接字选项,用于向后兼容。此选项设置套接字输入操作要处理的最小字节数。

SO_SNDLOWAT

INT

包括BSD UNIX的套接字选项,用于向后兼容。此选项设置套接字输出操作要处理的最小字节数。

SO_TYPE

INT

返回给定套接字的套接字类型(SOCK_STREAM或SOCK_DGRAM,例如套接字类型的设置不支持此套接字选项。



 


SO_CONDITIONAL_ACCEPT

将此套接字选项设置为TRUE会延迟连接的确认,直到调用​WSAAccept​条件函数为止 。如果为FALSE,则在调用条件功能之前可以接受连接,但如果条件功能拒绝该呼叫,则连接将被断开。在调用​listen​函数之前必须设置此选项 ,否则返回WSAEINVAL。SO_CONDITIONAL_ACCEPT仅支持TCP和ATM。

默认情况下,TCP将SO_CONDITIONAL_ACCEPT设置为FALSE,因此默认情况下,将在​WSAAccept​条件函数被调用之前接受连接 。当设置为TRUE时,必须在TCP连接超时之内进行条件决定。CF_DEFER连接仍然会超时。

默认情况下,ATM将SO_CONDITIONAL_ACCEPT设置为TRUE

SO_DEBUG

如果应用程序设置了SO_DEBUG选项,Windows Sockets服务提供商将被鼓励(但不是必需)提供输出调试信息。用于生成调试信息及其形式的机制超出了本文档的范围。

SO_GROUP_PRIORITY

保留以备将来使用套接字组。组优先级表示指定套接字相对于套接字组内其他套接字的相对优先级。值是非负整数,零对应于最高优先级。优先级值代表底层服务提供商关于如何分配潜在稀缺资源的提示。例如,当两个或更多个套接字都准备好传输数据时,最高优先级套接字(SO_GROUP_PRIORITY的最低值)应首先进行处理,其余的根据其相对优先级依次进行服务。

SO_KEEPALIVE


应用程序可以通过打开SO_KEEPALIVE套接字选项来请求TCP / IP提供商启用TCP连接上的保持活动数据包。Windows Sockets提供程序不需要支持使用keep-alives。如果是这样,精确的语义是实现特定的,但应符合关于​​IETF网站上​​提供的RFC 1122中规定的Internet主机 - 通信层要求的第4.2.3.6节。(此资源只能用英文提供)

如果由于保持活动而导致连接丢失,则错误代码 ​​WSAENETRESET​​​将返回到套接字上正在进行的任何调用,并且随后的任何调用将随​​WSAENOTCONN​​失败。

如果对具有​SO_KEEPALIVE​​的TCP套接字启用了保持活动,则默认TCP设置用于保持活动超时和间隔,除非通过使用​SIO_KEEPALIVE_VALS​​选项调用​WSAIoctl​函数 来更改这些值。

SO_LINGER

SO_LINGER选项控制未连接的数据在套接字上排队并执行​closesocket​时所采取的 操作。见 字关闭了,其中的SO_LINGER设置影响语义的方式描述 关闭套接字。应用程序通过创建​LERER​结构(由optval参数指向)来设置所需的行为 ,这些成员使用这些成员l_onoffl_linger进行适当的设置。

SO_REUSEADDR

默认情况下,不能绑定一个套接字(请参阅 ​bind​)到已经在使用的本地地址。然而,有时,可能需要以这种方式重用地址。由于每个连接都由本地和远程地址的组合唯一标识,所以只要远程地址不同,就将两个套接字绑定到相同的本地地址就没有问题。要通知Windows Sockets提供程序,因为所需的地址已被另一个套接字使用,应该不会禁止套接字上的 绑定,所以应用程序应该在发布绑定之前为套接字设置SO_REUSEADDR套接字选项 。该选项仅在绑定时解释 。 在不绑定到现有地址的套接字上设置该选项是不必要和无害的。绑定后设置或重置该选项对此或任何其他套接字没有影响。

SO_RCVBUF和SO_SNDBUF

当Windows Sockets实现支持SO_RCVBUF和SO_SNDBUF选项时,应用程序可以请求不同的缓冲区大小(更大或更小)。即使实施没有提供所请求的总额,对setsockopt的调用 也可以成功。应用程序必须使用相同的选项调用 ​getsockopt​来检查实际提供的缓冲区大小。

SO_RCVTIMEO和SO_SNDTIMEO

当使用 ​recv​功能时,如果在SO_RCVTIMEO指定的时间段内没有数据到达,则 recv功能完成。在Windows 2000之前的Windows版本中,随后使用​​WSAETIMEDOUT​​,接收到的任何数据都将失败。在Windows 2000及更高版本中,如果在SO_RCVTIMEO 指定的时间内没有数据到达,则 recv函数返回WSAETIMEDOUT,如果接收到数据,则 recv返回SUCCESS。

如果发送或接收操作在套接字上超时,套接字状态是不确定的,不应该使用; 在这种状态下的TCP插座有可能导致数据丢失,因为操作可以在操作完成的同一时间被取消。

PVD_CONFIG

此对象存储与s参数中指定的套接字相关联的服务提供商的配置信息。这种数据结构的确切格式是每个服务提供商所特有的。

TCP_NODELAY

TCP_NODELAY选项特定于TCP / IP服务提供商。如果启用TCP_NODELAY选项(反之亦然),Nagle算法将被禁用。该过程涉及当有未确认的数据已经在飞行中或缓冲发送数据时缓冲发送数据,直到可以发送全尺寸数据包。强烈建议TCP / IP服务提供商默认启用Nagle算法,对于绝大多数应用协议,Nagle算法可以提供显着的性能增强。但是,对于某些应用程序,该算法可能会阻碍性能,TCP_NODELAY可用于将其关闭。这些是发送许多小消息的应用程序,并且维护消息之间的时间延迟。

注意   当发出阻止Winsock调用(如 setsockopt)时,Winsock可能需要等待网络事件才能完成调用。在这种情况下,Winsock会执行一个可警告的等待,这可以通过在同一线程上安排的异步过程调用(APC)中断。在APC中发出另一个阻塞Winsock调用,该过程会在同一个线程上中断正在进行的阻塞Winsock调用,这将导致未定义的行为,绝对不能由Winsock客户端尝试。



 



示例代码

以下示例演示了setsockopt函数。



C ++





#ifndef UNICODE 
#define UNICODE
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <
winsock2.h>
#include < Ws2tcpip.h> #include <stdio.h> //链接ws2_32.lib
#pragma comment(lib,“Ws2_32.lib”)int main()
{ // ------------------------------------- - //声明变量
WSADATA wsaData;
SOCKET ListenSocket;
sockaddr_in服务; int iResult = 0;
BOOL bOptVal = FALSE; int bOptLen = sizeof(BOOL); int iOptVal = 0;
int iOptLen = sizeof(int); // --------------------------------------- //初始化Winsock
iResult = WSAStartup(MAKEWORD (2,2),&wsaData); if(iResult!= NO_ERROR){
wprintf(L “Error at WSAStartup()\ n”);
返回 1;
} // --------------------------------------- //创建一个监听套接字
ListenSocket =套接字(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(ListenSocket == INVALID_SOCKET){
wprintf(L “socket function failed with error:%u \ n”,WSAGetLastError());
WSACleanup(); 返回 1;
} // --------------------------------------- //将套接字绑定到本地IP地址//和端口27015
hostent * thisHost; char * ip;
u_short端口
端口= 27015;
thisHost = gethostbyname(“”);
ip = inet_ntoa(*(struct in_addr *)* thisHost-> h_addr_list);
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);
iResult = bind(ListenSocket,(SOCKADDR *)&service,sizeof(service));
if(iResult == SOCKET_ERROR){
wprintf(L “bind failed with error%u \ n”,WSAGetLastError());
关闭套接字(ListenSocket);
WSACleanup(); 返回 1;
} // --------------------------------------- //初始化变量并调用setsockopt。// SO_KEEPALIVE参数是一个套接字选项//使套接字在会话上发送keepalive消息//。SO_KEEPALIVE套接字选项//需要将一个布尔值传递给// setsockopt函数。如果为TRUE,则套接字//配置为发送keepalive消息,如果FALSE //套接字配置为不发送keepalive消息。//这段代码通过使用getsockopt函数检查套接字上的SO_KEEPALIVE的状态来测试setsockopt函数// 。
bOptVal = TRUE;
iResult = getsockopt(ListenSocket,SOL_SOCKET,SO_KEEPALIVE,(char *)&iOptVal,&iOptLen);
if(iResult == SOCKET_ERROR){
wprintf(L “getsockopt for SO_KEEPALIVE failed with error:%u \ n”,WSAGetLastError());
} else
wprintf(L “SO_KEEPALIVE Value:%ld \ n”,iOptVal);
iResult = setsockopt(ListenSocket,SOL_SOCKET,SO_KEEPALIVE,(char *)&bOptVal,bOptLen);
if(iResult == SOCKET_ERROR){
wprintf(L “setsockopt for SO_KEEPALIVE failed with error:%u \ n”,WSAGetLastError());
} else
wprintf(L “Set SO_KEEPALIVE:ON \ n”);
iResult = getsockopt(ListenSocket,SOL_SOCKET,SO_KEEPALIVE,(char *)&iOptVal,&iOptLen);
if(iResult == SOCKET_ERROR){
wprintf(L “getsockopt for SO_KEEPALIVE failed with error:%u \ n”,WSAGetLastError());
} else
wprintf(L “SO_KEEPALIVE Value:%ld \ n”,iOptVal);
关闭套接字(ListenSocket);
WSACleanup(); 返回 0;
}



IrDA插座注意事项

在使用IrDA的Windows套接字开发应用程序时,请注意以下事项:

  • 必须明确地包含Af_irda.h头文件。
  • IrDA提供以下套接字选项:


类型

含义

IRLMP_IAS_SET

* IAS_SET

设置IAS属性

IRLMP_IAS_SET套接字选项使应用程序可以在本地IAS中设置单个类的单个属性。应用程序指定要设置的类,属性和属性类型。应用程序预期为传递的参数分配必要大小的缓冲区。

IrDA提供了一个存储基于IrDA的信息的IAS数据库。通过Windows Sockets 2接口可以访问对IAS数据库的访问,但这种访问通常不被应用程序使用,并且主要用于支持与不符合Windows Sockets 2 IrDA约定的非Windows设备的连接。

以下结构IAS_SET与IRLMP_IAS_SET setsockopt选项一起用于管理本地IAS数据库:



C ++





// #include <Af_irda.h>为此struct 

typedef struct _IAS_SET {
u_char irdaClassName [IAS_MAX_CLASSNAME]; char irdaAttribName [IAS_MAX_ATTRIBNAME];
u_long irdaAttribType; 工会
{
LONG irdaAttribInt; struct
{
u_long Len;
u_char OctetSeq [IAS_MAX_OCTET_STRING];
irdaAttribOctetSeq; struct
{
u_long Len;
u_long CharSet;
u_char UsrStr [IAS_MAX_USER_STRING];
irdaAttribUsrStr;
irdaAttribute;



以下结构IAS_QUERY与IRLMP_IAS_QUERY setsockopt选项一起用于查询对等体的IAS数据库:



C ++





// #include <Af_irda.h>为此struct 

typedef struct _WINDOWS_IAS_QUERY {
u_char irdaDeviceID [4]; char irdaClassName [IAS_MAX_CLASSNAME];
char irdaAttribName [IAS_MAX_ATTRIBNAME];
u_long irdaAttribType; 工会
{
LONG irdaAttribInt; struct
{
u_long Len;
u_char OctetSeq [IAS_MAX_OCTET_STRING];
irdaAttribOctetSeq; struct
{
u_long Len;
u_long CharSet;
u_char UsrStr [IAS_MAX_USER_STRING];
irdaAttribUsrStr;
irdaAttribute;
} IAS_QUERY,* PIAS_QUERY,FAR * LPIASQUERY;



许多SO_级套接字选项对IrDA无效。只有SO_LINGER被特别支持。

Windows Phone 8: Windows Phone 8及更高版本上的Windows Phone Store应用程序支持此功能。

Windows 8.1Windows Server 2012 R2:Windows 8.1,Windows Server 2012 R2和更高版本上的Windows Store应用程序支持此功能。

要求



最低支持客户端

Windows 8.1,Windows Vista [桌面应用程序| Windows Store应用程序]

最低支持服务器

Windows Server 2003 [桌面应用程序| Windows Store应用程序]

最低支持的手机

Windows Phone 8


Winsock2.h

图书馆

WS2_32.LIB

DLL

WS2_32.DLL


标签:02,选项,UDP,--,TCP,Windows,SO,接字,IAS
From: https://blog.51cto.com/u_15872025/5845483

相关文章

  • HDMI协议详细
     本文从软件工程师角度对HDMI spec进行解析,基于的spec版本为1.4,也是设备支持最多最成熟的版本,目前最新版本为2.0。1概述 HDMI(High-DefinitionMultifaceInterfa......
  • Hibernate三种实体状态(五)
    一.Hibernate的三种实体状态Hibernate有三种实体状态,有瞬时态(transiant),持久态(persistent),游离态(detached)。简单理解就是,瞬时态指的是刚New新建的一个对象,没有放......
  • 第六章21
    【题目描述】从输入的n个整数中查找给定的SearchNum(若存在必唯一)。如果找到,输出SearchNum的位置(从0开始数);如果没有找到,输出“NotFound”。【输入】有两行。第1行是两个......
  • 一个项目涉及到的50个Sql语句
    一个项目涉及到的50个Sql语句/*标题:一个项目涉及到的50个Sql语句(整理版)作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)时间:2010-05-10地点:重庆航天职业学院说明:以下五十......
  • 第六章22
    【题目描述】幼儿园的老师每天都会教小班的孩子们学习认识100以内的数字,一学期结束了,老师出了一道题想看看孩子们认识数字的效果。老师给出了多张数字卡片,想让孩子们自己......
  • C语言必背18个经典程序
    C语言必背18个经典程序1、/*输出9*9口诀。共9行9列,i控制行,j控制列。*/#include"stdio.h"main(){inti,j,result;for(i=1;i<10;i++){for(j=1;j<10;j++){......
  • 进程的来龙去脉
    进程的创建是一件相当复杂的事情,其中要包涵很多工作,我们可以通过反汇编来看看CreateProcess()。为了启动一个进程可有以下几步:1.可执行文件必须被以FILE_EXECYTE存取方式打开......
  • 获取斗鱼房间以及直播地址
    douyu.py#-*-coding:utf-8-*-importrequestsimportre,sysimportexecjsimporttimeimporthashlibdefget_tt():tt1=str(int(time.time()))tt2=str(int((ti......
  • 第六章23
    【题目描述】给定两个整型数组,要求找出不是两者共有的元素。【输入】有两行。第1行先给出正整数n(n≤20),随后是n个整数,其间以空格分隔。第2行先给出正整数m(m≤20),随后是m个......
  • Android Notes|细数「十大布局」那些事儿
    最近的心情,最近的状态,似乎没法说个一二三四五。做Android好几年了,从单纯的Android,到现在大杂烩,这个滋味儿,真的是百感交汇。文章的内容类型从来都是Notes,这次对老本行进......