网络编程Winsock——connect

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值