首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WinSock错误10061

WinSock错误10061
EN

Stack Overflow用户
提问于 2012-04-27 20:33:18
回答 2查看 9.2K关注 0票数 0

我已经使用winsock编写了一个简单的客户机/服务器应用程序。服务器和客户机通过本地主机上的TCP端口76567 (我选择的一个随机数)进行连接和通信。我已经在三台台式机上测试了它,两台运行XP,另一台运行Win7,我还在四台笔记本电脑上测试了它,三台运行Win7,一台运行XP。该应用程序在所有台式机和XP笔记本电脑上都工作得很好,但是在所有三台Win7笔记本电脑上,当客户端尝试连接到服务器时,我得到了错误10061!

我已经关闭了防火墙,但问题仍然存在,我还查看了一下导致此错误的原因,发现客户端似乎正在尝试连接到未侦听的服务器。但是,对listen()的服务器调用成功返回!奇怪的是,这个问题似乎只发生在Win7笔记本电脑上,你有什么想法?

下面是我的套接字初始化代码:

代码语言:javascript
运行
复制
// Initialise Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if(iResult != 0)
{
    printf("WSAStartup failed: %d\n", iResult);
}

// Create a server socket
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if(iResult != 0)
{
    printf("getaddrinfo failed: %d\n", iResult);
    WSACleanup();
}

// Create a socket to listen for clients
listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if(listenSocket == INVALID_SOCKET)
{
    printf("Error at socket(): %d\n", WSAGetLastError());

    freeaddrinfo(result);
    WSACleanup();
}

// Bind socket to ip address and port
iResult = bind(listenSocket, result->ai_addr, (int) result->ai_addrlen);
if(iResult == SOCKET_ERROR)
{
    printf("bind failed with error: %d\n", WSAGetLastError());

    freeaddrinfo(result);
    closesocket(listenSocket);
    WSACleanup();
}
freeaddrinfo(result);

// Listen for connection requests
if(listen(listenSocket, SOMAXCONN) != 0)
{
    printf("Listen failed with error: %d\n", WSAGetLastError());

    closesocket(listenSocket);
    WSACleanup();
}

非常感谢:)

EN

回答 2

Stack Overflow用户

发布于 2012-07-14 05:39:25

IP端口是16位整数,因此允许的最大端口号为0xFFFF (65535)。这里发生的是一种整数溢出。由于您所需的端口号(76567)不适合16位,因此该数字被截断,仅使用最低的16位。这将为您提供端口号11031。因为htons()的参数不能在uint16_t中找到,所以addr.sin_port = htons(76567);行应该会给你一个编译器警告。

票数 2
EN

Stack Overflow用户

发布于 2012-04-28 08:41:34

getaddrinfo()返回符合给定hints条件的所有可用地址的链表。即使计算机只有一个网络适配器,也可以为其分配多个IP地址,即使对于localhost也是如此。您正在将服务器套接字绑定到getaddrinfo()找到的第一个IP /端口对,因此,客户端可能正在尝试连接到另一个真正没有在服务器上侦听的IP/端口,例如,如果服务器绑定到您的局域网/互联网IP,但客户端却连接到127.0.0.1。除非服务器绑定到127.0.0.1,否则客户端无法连接到127.0.0.1

在多宿主/多IP环境中,您应该在调用bind()时使用通配符0.0.0.0 IP(也称为INADDR_ANY),而不是result->ai_addr。这将把套接字绑定到所有已安装网络适配器的所有可用IP。这样,客户端就可以连接到服务器绑定到的任何IP,包括127.0.0.1。实际上,根据您所展示的代码,您甚至根本不需要使用getaddrinfo()

代码语言:javascript
运行
复制
// Initialise Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if(iResult != 0)
{
    printf("WSAStartup failed: %d\n", iResult);
}

// Create an IPv4 server socket to listen for IPv4 clients
listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(listenSocket == INVALID_SOCKET)
{
    printf("Error at socket(): %d\n", WSAGetLastError());
    WSACleanup();
}

// Bind socket to IPv4 address and port
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(76567);
addr.sin_addr.s_addr = INADDR_ANY;

iResult = bind(listenSocket, (sockaddr*)&addr, sizeof(addr));
if(iResult == SOCKET_ERROR)
{
    printf("bind failed with error: %d\n", WSAGetLastError());
    closesocket(listenSocket);
    WSACleanup();
}

// Listen for IPv4 connection requests
if(listen(listenSocket, SOMAXCONN) != 0)
{
    printf("Listen failed with error: %d\n", WSAGetLastError());
    closesocket(listenSocket);
    WSACleanup();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10350683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档