connect 函数 (winsock2.h)
connect 函数与指定的套接字建立连接。
int WSAAPI connect(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen
);
[in] s
标识未连接的套接字的描述符。
[in] name
指向应建立连接的 sockaddr 结构的指针。
[in] namelen
name 参数指向的 sockaddr 结构的长度(以字节为单位)。
如果未发生错误, 则连接 返回零。 否则,它将返回SOCKET_ERROR,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。
在阻塞套接字上,返回值指示连接尝试成功或失败。
使用非阻止套接字时,无法立即完成连接尝试。 在这种情况下, 连接 将返回SOCKET_ERROR, WSAGetLastError 将返回 WSAEWOULDBLOCK。 在这种情况下,有三种可能的方案:
- 使用 select 函数通过检查套接字是否可写来确定连接请求的完成情况。
- 如果应用程序使用 WSAAsyncSelect 来指示对连接事件感兴趣,则应用程序将收到FD_CONNECT通知,指示 连接 操作已完成 (成功或未) 。
- 如果应用程序使用 WSAEventSelect 来指示对连接事件的兴趣,则将向关联的事件对象发出信号,指示 连接 操作已完成 (成功或未) 。
在非阻止套接字上完成连接尝试之前,在连接成功完成时,在同一套接字上进行 连接 的所有后续调用都将失败并出现错误代码 WSAEALREADY 和 WSAEISCONN 。 由于 Windows 套接字规范版本 1.1 中的多义性,在连接已挂起时从 连接 返回的错误代码可能因实现而异。 因此,不建议应用程序使用多个调用进行连接以检测连接完成情况。 如果他们这样做,则必须准备好处理 WSAEINVAL 和 WSAEWOULDBLOCK 错误值的方式与处理 WSAEALREADY 的方式相同,以确保可靠的操作。
如果返回的错误代码指示连接尝试失败 (即 WSAECONNREFUSED、 WSAENETUNREACH、 WSAETIMEDOUT) 应用程序可以为同一套接字再次调用 connect 。
错误代码 | 含义 |
---|---|
在使用此函数之前,必须成功调用 WSAStartup 。 | |
网络子系统失败。 | |
套接字的本地地址已在使用中,并且未将套接字标记为允许使用 SO_REUSEADDR 重用地址。 此错误通常在执行绑定时发生,但如果绑定是本地 IP 地址的通配符地址 (INADDR_ANY或in6addr_any) ,则可能会延迟到连接功能。 特定地址需要由 connect 函数隐式绑定。 | |
阻止的 Windows 套接字 1.1 调用已通过 WSACancelBlockingCall 取消。 | |
阻止 Windows Sockets 1.1 调用正在进行,或者服务提供程序仍在处理回调函数。 | |
正在指定的套接字上进行非阻止 连接 调用。
注意 为了保持向后兼容性,此错误以 WSAEINVAL 的形式报告给链接到 Winsock.dll 或 Wsock32.dll 的 Windows 套接字 1.1 应用程序。
|
|
远程地址不是有效的地址 (,例如 INADDR_ANY 或 in6addr_any) 。 | |
指定系列中的地址无法与此套接字一起使用。 | |
尝试连接被强制性拒绝。 | |
名称指向的 sockaddr 结构包含关联的地址系列地址格式不正确,或者 namelen 参数太小。 如果 name 参数所指向的长度在 namelen 参数中指定的 sockaddr 结构不在用户地址空间的有效部分,则也会返回此错误。 | |
参数 s 是侦听套接字。 | |
仅) 面向连接的套接字 (已连接套接字。 | |
此时不可以从此主机访问该网络。 | |
套接字操作尝试访问无法访问的主机。 | |
注意 没有可用的缓冲区空间。 无法连接套接字。
|
|
s 参数中指定的描述符不是套接字。 | |
尝试连接超时,但未建立连接。 | |
:套接字标记为非阻止,无法立即完成连接。 | |
尝试将数据报套接字连接到广播地址失败,因为未启用 setsockopt 选项SO_BROADCAST。 |
connect 函数用于创建到指定目标的连接。 如果套接字 未绑定,则系统会将唯一值分配给本地关联,并将套接字标记为绑定。
对于面向连接的套接字 (例如,SOCK_STREAM) 类型,将使用 名称 (套接字命名空间中的地址发起到外部主机的活动连接;有关详细说明,请参阅 bind 和 sockaddr) 。
套接字调用成功完成后,套接字已准备好发送和接收数据。 如果 name 参数指定的结构的地址成员用零填充, 则连接 将返回错误 WSAEADDRNOTAVAIL。 重新连接活动连接的任何尝试都将失败,错误代码为 WSAEISCONN。
对于面向连接的非阻塞套接字,通常无法立即完成连接。 在这种情况下,此函数返回错误 WSAEWOULDBLOCK。 但是,该操作继续进行。
当成功或失败结果已知时,可能会以两种方式之一进行报告,具体取决于客户端注册通知的方式。
- 如果客户端使用 select 函数,则会在 writefds 集中报告成功,在 exceptfds 集中报告失败。
- 如果客户端使用函数 WSAAsyncSelect 或 WSAEventSelect,则会使用 FD_CONNECT 通知,并且与FD_CONNECT关联的错误代码指示成功或失败的特定原因。
如果未立即完成连接,客户端应等待连接完成,然后尝试使用 setsockopt 设置套接字选项。 不支持在连接正在进行时调用 setsockopt。
对于无连接套接字 (例如,SOCK_DGRAM) 类型, 连接 执行的操作只是为了建立可用于后续 发送/ WSASend 和 recv/ WSARecv 调用的默认目标地址。 从指定的目标地址以外的地址接收的任何数据报将被丢弃。 如果 name 指定的结构的地址成员用零填充,则套接字将断开连接。 然后,默认远程地址将不确定,因此 send/ WSASend 和 recv/ WSARecv 调用将返回错误代码 WSAENOTCONN。 但是, sendto/ WSASendTo 和 recvfrom/ WSARecvFrom 仍可使用。 只需再次调用 连接 即可更改默认目标,即使套接字已连接也是如此。 如果 名称 与上一个 连接不同,则放弃排队接收的任何数据报。
对于无连接套接字, 名称 可以指示任何有效的地址,包括广播地址。 但是,若要连接到广播地址,套接字必须使用 setsockopt 来启用SO_BROADCAST选项。 否则, 连接 将失败,错误代码 为 WSAEACCES。
当套接字之间的连接断开时,应放弃已连接的套接字,并创建新的套接字。 当在连接的套接字上出现问题时,应用程序必须放弃套接字并再次创建套接字,以便返回到稳定点。
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")
int wmain()
{
//----------------------
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for connecting to server
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(27015);
//----------------------
// Connect to server.
iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));
if (iResult == SOCKET_ERROR) {
wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
wprintf(L"Connected to server.\n");
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
WSACleanup();
return 0;
}
有关使用 connect 函数的另一个示例,请参阅 入门 With Winsock。
- 必须显式包含 Af_irda.h 头文件。
- 如果在媒体访问级别检测到现有的 IrDA 连接,则返回 WSAENETDOWN 。
- 如果存在与具有不同地址的设备的活动连接,则返回 WSAEADDRINUSE 。
- 如果套接字已连接或独占/多路复用模式更改失败,则返回 WSAEISCONN 。
- 如果套接字以前绑定到本地服务名称以使用 绑定接受传入连接,则返回 WSAEINVAL 。 请注意,绑定套接字后,它不能用于建立出站连接。
IrDA 使用表单sockaddr_irda地址实现 connect 函数。 通常,客户端应用程序将使用套接字功能创建一个套接字,使用“IRLMP_ENUMDEVICES套接字”选项扫描 IrDA 设备的邻近区域,从返回的列表中选择设备,形成地址,然后调用 connect。 阻止语义和非阻止语义之间没有区别。
最低受支持的客户端 | Windows Vista [桌面应用 | UWP 应用] |
最低受支持的服务器 | Windows Server 2003 [桌面应用 | UWP 应用] |
目标平台 | Windows |
标头 | winsock2.h |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |