connect 与特定的套接字建立连接
int connect( _In_ SOCKET s, _In_ const struct sockaddr *name, _In_ int namelen );
返回值分为两种情况:阻塞和非阻塞。
对于阻塞的套接字:0表示正确,SOCKET_ERROR表示错误。详细错误信息使用WSAGetLastError。
对于非阻塞套接字,不能立刻判断连接是否完成。函数会返回SOCKET_ERROR,但这并不表示出错,调用WSAGetLastError会得到WSAEWOULDBLOCK。需要分三种情况讨论:
使用select函数来决定连接请求的完成,通过查看套接字是否可写。
如果应用程序使用WSAAsyncSelect来处理连接事件,它会收到FD_CONNECT通知来表示连接操作已经完成。(无论是否成功)
如果应用程序使用WSAEventSelect来处理连接事件,那么相关的事件对象会发出信号来表示连接操作已经完成。(无论是否成功)
如果s没有绑定,系统会给它分配一个系统的唯一值,并标为已绑定。
是否成功连接:
对于面向连接的非阻塞套接字
1、客户端使用select函数,成功信息保存在writefds里,失败的在exceptfds里。
2、客户端使用WSAAyncSelect或者WSAEventSelect,通知信息使用FD_CONNECT,错误码也使用FD_CONNECT表示,表示成功或者因为特别的原因而失败。
对于面向无连接的套接字:任何不是目的地址的数据包都会被丢弃。如果name为0,则连接会断开,然后send/WSASend和recv/WSARecv会调用失败并且返回错误码WSAENOTCONN。但是sendto/WSASendTo和recvfrom/WSARecvFrom仍旧可以用。即使套接字已经连接了,默认的目的地也可以通过仅仅再次调用connect而改变,属于之前name的数据包会被丢弃。
对于无连接的套接字,name可以表示任何可用地址,包括广播地址。但是必须用setsockopt来打开O_BROADCAST设置。(否则失败并得到错误码WSAEACCES)
这一段不知道什么意思,看起来很厉害:
When a connection between sockets is broken, the socket that was connected should be discarded and new socket should be created. When a problem develops on a connected socket, the application must discard the socket and create the socket again in order to return to a stable point.
MSDN上的示例代码:
; 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; }