大佬教程收集整理的这篇文章主要介绍了Windows – ConnectEx要求套接字“最初绑定”,但是要什么?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
这是我目前的理解:在调用ConnectEx之前,bind将套接字调用到INADDR_ANY和端口0(除非它已被绑定):
struct sockaddr_in addr; ZeroMemory(&addr,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = 0; rc = bind(sock,(SOCKADDR*) &addr,sizeof(addr)); if (rc != 0) { ... bind Failed; call WSAGetLastError to see why ... }
或者对于IPv6套接字:
struct sockaddr_in6 addr; ZeroMemory(&addr,sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_addr = in6addr_any; addr.sin6_port = 0; rc = bind(sock,sizeof(addr)); if (rc != 0) { ... bind Failed; call WSAGetLastError to see why ... }
这允许操作系统为我们的套接字分配本地地址(而不是我们连接的远程地址). connect自动执行此步骤,但ConnectEx不会.
我的问题是:
>我的评估是否正确?
>有没有办法对地址族进行无关的自动绑定,还是我必须手动处理AF_INET,AF_INET6,AF_BTH(蓝牙)等各个?
使用COnnectEx示例(也在Gist:https://gist.github.com/4158972上):
#include <st@L_874_20@.h> #include <WinSock2.h> #include <MSWSock.h> #include <WS2tcpip.h> #pragma comment(lib,"Ws2_32.lib") struct mswsock_s { LPFN_CONNECTEX ConnectEx; } mswsock; static BOOL load_mswsock(void) { SOCKET sock; DWORD dwBytes; int rc; /* Dummy socket needed for WSAIoctl */ sock = socket(AF_INET,SOCK_STREAM,0); if (sock == INVALID_SOCKET) return falSE; { GUID guid = WSAID_CONNECTEX; rc = WSAIoctl(sock,SIO_GET_EXTENSION_FUNCTION_POINTER,&guid,sizeof(guid),&mswsock.ConnectEx,sizeof(mswsock.ConnectEX),&dwBytes,NULL,null); if (rc != 0) return falSE; } rc = closesocket(sock); if (rc != 0) return falSE; return TRUE; } int main(int argc,char *argv[]) { int rc; BOOL ok; WSADATA wsaData; SOCKET sock; rc = WSAStartup(MAKEWORD(2,2),&wsaData); if (rc != 0) { printf("WSAStartup Failed: %d\n",rc); return 1; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { printf("Your computer is from the wrong millenium.\n"); WSACleanup(); return 1; } if (!load_mswsock()) { printf("Error loading mswsock functions: %d\n",WSAGetLastError()); return 1; } sock = socket(AF_INET,0); if (sock == INVALID_SOCKET) { printf("socket: %d\n",WSAGetLastError()); return 1; } /* ConnectEx requires the socket to be initially bound. */ { struct sockaddr_in addr; ZeroMemory(&addr,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = 0; rc = bind(sock,sizeof(addr)); if (rc != 0) { printf("bind Failed: %d\n",WSAGetLastError()); return 1; } } /* Issue ConnectEx and wait for the operation to complete. */ { OVERLAPPED ol; ZeroMemory(&ol,sizeof(ol)); sockaddr_in addr; ZeroMemory(&addr,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("173.194.37.36"); // google.com addr.sin_port = htons(80); ok = mswsock.ConnectEx(sock,sizeof(addr),&ol); if (ok) { printf("ConnectEx succeeded immediately\n"); } else if (WSAGetLastError() == ERROR_IO_PENDING) { printf("ConnectEx pending\n"); DWORD numbytes; ok = GetOverlappedResult((HANDLE) sock,&ol,&numbytes,TRUE); if (ok) printf("ConnectEx succeeded\n"); else printf("ConnectEx Failed: %d\n",WSAGetLastError()); } else { printf("ConnectEx Failed: %d\n",WSAGetLastError()); return 1; } } /* Make the socket more well-behaved. */ rc = setsockopt(sock,SOL_SOCKET,SO_updatE_CONNECT_COntexT,0); if (rc != 0) { printf("SO_updatE_CONNECT_COntexT Failed: %d\n",WSAGetLastError()); return 1; } /* This will fail if SO_updatE_CONNECT_COntexT was not performed. */ rc = shutdown(sock,SD_BOTH); if (rc != 0) { printf("shutdown Failed: %d\n",WSAGetLastError()); return 1; } printf("Done\n"); return 0; }
以上是大佬教程为你收集整理的Windows – ConnectEx要求套接字“最初绑定”,但是要什么?全部内容,希望文章能够帮你解决Windows – ConnectEx要求套接字“最初绑定”,但是要什么?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。