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