1:加载套接字库,创建套接字(WSAStartup()/socket()); 2:绑定套接字到一个IP地址和一个端口上(bind()); 3:将套接字设置为监听模式等待连接请求(listen()); 4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept()); 5:用返回的套接字和客户端进行通信(send()/recv()); 6:返回,等待另一连接请求; 7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
#ifdef WIN32 #include <winsock2.h> #else #include <sys/socket.h> #include <net/if.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <netdb.h> #include <sys/select.h> #endif bool InstanceServer::getAvailableListenPort(std::string &port) { bool result = true; #ifdef WIN32 WSADATA wsa; /*初始化socket资源*/ if (WSAStartup(MAKEWORD(1, 1), &wsa) != 0) {return false; //代表失败 } #endif // 1. 创建一个socket int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 2. 创建一个sockaddr,并将它的端口号设为0 struct sockaddr_in addrto; memset(&addrto, 0, sizeof(struct sockaddr_in)); addrto.sin_family = AF_INET; addrto.sin_addr.s_addr = inet_addr(CLIENT_IP.c_str()); addrto.sin_port = 0; // 3. 绑定 int ret = ::bind(sock, (struct sockaddr *)&(addrto), sizeof(struct sockaddr_in)); if (0 != ret) {return false; } // 4. 利用getsockname获取 struct sockaddr_in connAddr; memset(&connAddr, 0, sizeof(struct sockaddr_in)); #ifdef WIN32 int len = sizeof(connAddr); #else unsigned int len = sizeof(connAddr); #endif ret = ::getsockname(sock, (sockaddr*)&connAddr, &len); if (0 != ret) {return false; } port = (std::string)ntohs(connAddr.sin_port); // 获取端口号 #ifdef WIN32 if (0 != closesocket(sock)) #else if (0 != close(sock)) #endif { result = false; } return result; }