- C++ 黑客编程揭秘与防范(第3版)
- 冀云
- 741字
- 2020-06-27 17:48:51
2.2.1 基于TCP的通信
1.服务器端代码
回顾一下前面的知识,创建一个TCP的服务器端的程序需要调用的函数流程如下:
WSAStartup()->socket()->bind()->listen()->accept()->send()/recv()->closesocket()-> WSACleanup()
只要依次调用上面的函数就可以完成一个服务器端的程序了,是不是如同搭积木一样简单?服务器端的代码如下:
#include <stdio.h> #include <winsock2.h> #pragma comment (lib, "ws2_32") int main() { WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); // 创建套接字 SOCKET sLisent = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // 对sockaddr_in结构体填充地址、端口等信息 struct sockaddr_in ServerAddr; ServerAddr.sin_family = AF_INET; ServerAddr.sin_addr.S_un.S_addr = inet_addr("10.10.30.12"); ServerAddr.sin_port = htons(1234); // 绑定套接字与地址信息 bind(sLisent, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)); // 端口监听 listen(sLisent, SOMAXCONN); // 获取连接请求 sockaddr_in ClientAddr; int nSize = sizeof(ClientAddr); SOCKET sClient = accept(sLisent, (SOCKADDR *)&ClientAddr, &nSize); // 输出客户端使用的IP地址和端口号 printf("ClientIP=%s:%d\r\n",inet_ntoa(ClientAddr.sin_addr), ntohs(ClientAddr.sin_port)); // 发送消息 char szMsg[MAXBYTE] = { 0 }; lstrcpy(szMsg, "hello Client!\r\n"); send(sClient, szMsg, strlen(szMsg) + sizeof(char), 0); // 接收消息 recv(sClient, szMsg, MAXBYTE, 0); printf("Client Msg : %s \r\n", szMsg); WSACleanup(); return 0; }
这样一个服务器端的程序就完成了。为了起到演示的作用,不让多余的东西影响流程的清晰化,这里没有对API函数的返回值进行判断。在实际的开发中,为了保证程序的健壮性,应该对各函数的返回值进行判断,以免程序中产生异常。
由于代码中有详细的注释,并且前面对各Winsock函数有详细的介绍,这里就不再对代码进行解释了。
2.客户端代码
在客户端中同样也是调用前面介绍的API函数进行搭积木式的编程就可以了。客户端的代码调用API的流程如下:
WSAStartup()->socket()->connect()->send()/recv()->closesocket()->WSACleanup()
有了调用的流程,就可以开始完成代码了。客户端的代码如下:
#include <stdio.h> #include <winsock2.h> #pragma comment (lib, "ws2_32") int main() { WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); // 创建套接字 SOCKET sServer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // 对sockaddr_in结构体填充地址、端口等信息 struct sockaddr_in ServerAddr; ServerAddr.sin_family = AF_INET; ServerAddr.sin_addr.S_un.S_addr = inet_addr("10.10.30.12"); ServerAddr.sin_port = htons(1234); // 连接服务器 connect(sServer, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)); char szMsg[MAXBYTE] = { 0 }; // 接收消息 recv(sServer, szMsg, MAXBYTE, 0); printf("Server Msg : %s \r\n", szMsg); // 发送消息 lstrcpy(szMsg, "hello Server!\r\n"); send(sServer, szMsg, strlen(szMsg) + sizeof(char), 0); WSACleanup(); return 0; }
以上代码就是客户端的代码,同样也非常简单。在VC6中创建控制台的应用程序,在创建项目是选择“Win32 Console Application”。这里要分别为服务器端程序和客户端程序创建项目,然后分别将服务器端代码和客户端代码进行编译连接。代码都编译连接完成以后,首先运行服务器端程序,再运行客户端程序,这样第一个基于TCP的服务器端程序和客户端程序就完成了。