windows上的套接字选项TCP_节点延迟需要8位布尔值?
下面是我的示例代码(很抱歉,它太长了): 有人能复制这个吗? 注意:我使用的是Win7,x64,使用VS2010编译x32应用程序 上的文档说明我应该使用windows上的套接字选项TCP_节点延迟需要8位布尔值?,c,sockets,visual-studio-2010,winsock2,getsockopt,C,Sockets,Visual Studio 2010,Winsock2,Getsockopt,下面是我的示例代码(很抱歉,它太长了): 有人能复制这个吗? 注意:我使用的是Win7,x64,使用VS2010编译x32应用程序 上的文档说明我应该使用BOOL。 上的文档说明我应该使用DWORD。然而,两者都不起作用。当您将OPT_TYPE设置为8位类型(例如char)时,它可以工作。我是否遗漏了文档中的某些内容?您能否在第一次调用getsockopt()之前和之后检查“flagLength”的值?在此之前,它应该是4,我猜,它是“1”之后,因为只有一个字节写入到您的标志,这完美地解释了结果
BOOL
。
上的文档说明我应该使用
DWORD
。然而,两者都不起作用。当您将OPT_TYPE
设置为8位类型(例如char
)时,它可以工作。我是否遗漏了文档中的某些内容?您能否在第一次调用getsockopt()
之前和之后检查“flagLength”的值?在此之前,它应该是4,我猜,它是“1”之后,因为只有一个字节写入到您的标志,这完美地解释了结果-256和-255。您是对的,根据文档,在调用getsockopt()之后,flagLength应该是4。您必须传递一个指向选项长度的指针的原因是:函数更新指向的长度,告诉您它写入选项值的字节数。看起来它一定只写了一个。一个快速而肮脏的解决方法可能是在调用之前将选项值设置为0
,而不是设置为-1
。更可靠的方法是在计算值时忽略任何未设置的字节。@Ctx您是对的!我更新了问题acordingly@Ctx,你又对了。我想,对于我来说,在周一早上看代码还为时过早。但是,尽管winsock的getsockopt()
在选项长度方面的行为与其文档中所述的不同,但问题仍然可以通过查看它实际报告的选项长度来检测到,甚至可以自动解决。当标志
为BOOL
时,代码将标志初始化为-1
(0xffffff
),然后getsockopt()
返回flaglength=1
,这意味着只设置了第一个字节(设置为0x00
),剩下的3个字节为0xFF
。这就是-256
(0xFFFFFF00
)的来源。如果标志
被初始化为0
而不是-1
,标志
将以0x00000000
结束,并且在第一次getsockopt()
之后检查FALSE
将成功。但是,是的,微软应该修改文档,说明TCP\u NODELAY
使用char
,但是,BOOL
在正确初始化时“工作”良好。
#include "stdafx.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
typedef BOOL OPT_TYPE;
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
int handle= socket(AF_INET, SOCK_STREAM, 0);
if(SOCKET_ERROR == handle )
{
int error = WSAGetLastError();
printf("ERROR in socket: errno: %d\n", error);
return error;
}
OPT_TYPE flag = -1;
int flagLength = sizeof(flag);
if (SOCKET_ERROR == getsockopt(handle, IPPROTO_TCP, TCP_NODELAY,
reinterpret_cast<char*>(&flag), &flagLength))
{
int error = WSAGetLastError();
printf("ERROR in getsockopt: errno: %d\n", error);
return error;
}
if(TRUE != flag && FALSE != flag)
{
printf("ERROR in getsockopt (default value): flag is invalid: %d, length is %d\n", flag, flagLength);
}
OPT_TYPE setflag = TRUE;
if (SOCKET_ERROR == setsockopt(handle, IPPROTO_TCP, TCP_NODELAY,
reinterpret_cast<char*>(&setflag), flagLength))
{
int error = WSAGetLastError();
printf("ERROR in getsockopt: errno: %d\n", error);
return error;
}
if (SOCKET_ERROR == getsockopt(handle, IPPROTO_TCP, TCP_NODELAY,
reinterpret_cast<char*>(&flag), &flagLength))
{
int error = WSAGetLastError();
printf("ERROR in getsockopt: errno: %d\n", error);
return error;
}
if(TRUE != flag && FALSE != flag)
{
printf("ERROR in getsockopt (default value): flag is invalid: %d, length is %d\n", flag, flagLength);
}
setflag = FALSE;
if (SOCKET_ERROR == setsockopt(handle, IPPROTO_TCP, TCP_NODELAY,
reinterpret_cast<char*>(&setflag), flagLength))
{
int error = WSAGetLastError();
printf("ERROR in getsockopt: errno: %d\n", error);
return error;
}
if (SOCKET_ERROR == getsockopt(handle, IPPROTO_TCP, TCP_NODELAY,
reinterpret_cast<char*>(&flag), &flagLength))
{
int error = WSAGetLastError();
printf("ERROR in getsockopt: errno: %d\n", error);
return error;
}
if(TRUE != flag && FALSE != flag)
{
printf("ERROR in getsockopt (default value): flag is invalid: %d, length is %d\n", flag, flagLength);
}
return 0;
}
ERROR in getsockopt (default value): flag is invalid: -256, length is 1
ERROR in getsockopt (default value): flag is invalid: -255, length is 1
ERROR in getsockopt (default value): flag is invalid: -256, length is 1