本篇文章将介绍如何使用 winsock 来实现 Client 客户端 和 Server 服务器应用程序。由于 Client 和 Server 的具体实现有所不同,所以本文将分成两部分来对 Client 和 Server 的实现进行讲解。
运行环境
Windows 10
Visual Studio Community 2017 (version 15.9.17)
Server 的实现
Server 的运行步骤如下:
初始化 Winsock。(Initialize Winsock.)
创建一个socket。(Create a socket.)
绑定 socket。(Bind the socket.)
监听客户端的 socket。(Listen on the socket for a client.)
接受客户端的连接请求。(Accept a connection from a client.)
接收和发送数据。(Receive and send data.)
断开连接。(Disconnect.)
创建 Winsock 应用
打开 visual studio,创建一个空应用,并命名为 myserver。
然后新建一个空的 c++ 源文件,并命名为 main.cpp。
然后确认编译环境中的包含目录,库目录和源码路径中包含 Microsoft Windows Software Development Kit (SDK)。由于在安装 Visual Studio的时候,已经安装了 Microsoft Windows SDK,所以这些已经默认包含到了相应的环境中。不需要再自己添加。
typedefstructaddrinfo { int ai_flags; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST int ai_family; // PF_xxx int ai_socktype; // SOCK_xxx int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6 size_t ai_addrlen; // Length of ai_addr char * ai_canonname; // Canonical name for nodename _Field_size_bytes_(ai_addrlen) structsockaddr * ai_addr; // Binary address structaddrinfo * ai_next; // Next structure in linked list }
// Resolve the local address and port to be used by the server iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if (iResult != 0) { std::cout << "getaddrinfo failed: " << iResult << std::endl; WSACleanup(); return1; }
然后为服务器创建一个名为 ListenSocket 的 SOCKET 对象,以监听客户端连接。
SOCKET ListenSocket = INVALID_SOCKET;
然后调用 socket 函数,将返回值赋给 SOCKET 对象并进行错误检查。
// Create a SOCKET for the server to listen for client connections
// shutdown the send half of the connection since no more data will be sent iResult = shutdown(ClientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { std::cout << "shutdown failed:" << WSAGetLastError() << std::endl; closesocket(ClientSocket); WSACleanup(); return1; }
// shutdown the send half of the connection since no more data will be sent iResult = shutdown(ConnectSocket, SD_SEND); if (iResult == SOCKET_ERROR) { std::cout << "shutdown failed: " << WSAGetLastError() << std::endl; closesocket(ConnectSocket); WSACleanup(); system("pause"); return1; }