云计算百科
云计算领域专业知识百科平台

VC++实现++tcp网络通讯服务器+客户端(附带源码)

VC++ 实现 TCP 网络通信(服务器 + 客户端)

本文将展示如何使用 VC++ 实现一个简单的 TCP 网络通信应用,包括服务器端和客户端。服务器端负责监听客户端请求并返回数据,而客户端向服务器发送请求并接收响应。

我们将使用 Windows API 中的 Winsock 库来实现网络通信。Winsock 是 Windows 平台上的网络编程接口,支持 TCP/IP 网络通信协议。

项目介绍

本项目的目标是通过使用 Winsock 编写一个简单的 TCP 服务器和客户端。服务器端监听特定的端口,等待客户端连接。客户端连接到服务器并发送请求,服务器返回响应。我们将用 send() 和 recv() 函数来发送和接收数据。

相关知识

  • Winsock 编程:

    • WSAStartup:初始化 Winsock 库。
    • socket:创建一个套接字。
    • bind:绑定套接字到本地地址和端口。
    • listen:使套接字处于监听状态。
    • accept:接受客户端的连接。
    • send 和 recv:发送和接收数据。
    • closesocket:关闭套接字。
    • WSACleanup:清理 Winsock。
  • TCP 和 UDP:

    • 本项目使用的是 TCP 协议,确保数据传输可靠并按顺序到达。
  • 代码结构

  • 服务器端:

    • 初始化 Winsock 库。
    • 创建套接字并绑定到本地 IP 地址和端口。
    • 监听客户端的连接请求。
    • 接受客户端连接并进行数据交换。
    • 关闭连接。
  • 客户端:

    • 初始化 Winsock 库。
    • 创建套接字并连接到服务器。
    • 发送数据到服务器并接收服务器响应。
    • 关闭连接。
  • 服务器端代码

    #include <winsock2.h>
    #include <iostream>
    #include <string>

    #pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库

    // 服务器端
    int main() {
    WSADATA wsaData;
    SOCKET listenSocket, clientSocket;
    sockaddr_in serverAddr, clientAddr;
    int clientAddrSize = sizeof(clientAddr);
    char recvBuffer[512];

    // 初始化 Winsock 库
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
    std::cerr << "Winsock initialization failed." << std::endl;
    return 1;
    }

    // 创建监听套接字
    listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (listenSocket == INVALID_SOCKET) {
    std::cerr << "Socket creation failed." << std::endl;
    WSACleanup();
    return 1;
    }

    // 配置服务器地址
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8080); // 设置端口
    serverAddr.sin_addr.s_addr = INADDR_ANY; // 监听所有接口

    // 绑定套接字到地址
    if (bind(listenSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
    std::cerr << "Bind failed." << std::endl;
    closesocket(listenSocket);
    WSACleanup();
    return 1;
    }

    // 开始监听客户端连接
    if (listen(listenSocket, 1) == SOCKET_ERROR) {
    std::cerr << "Listen failed." << std::endl;
    closesocket(listenSocket);
    WSACleanup();
    return 1;
    }

    std::cout << "Waiting for client connection…" << std::endl;

    // 接受客户端连接
    clientSocket = accept(listenSocket, (struct sockaddr*)&clientAddr, &clientAddrSize);
    if (clientSocket == INVALID_SOCKET) {
    std::cerr << "Accept failed." << std::endl;
    closesocket(listenSocket);
    WSACleanup();
    return 1;
    }

    std::cout << "Client connected!" << std::endl;

    // 接收数据
    int bytesReceived = recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);
    if (bytesReceived > 0) {
    recvBuffer[bytesReceived] = '\\0'; // 添加字符串结束符
    std::cout << "Received from client: " << recvBuffer << std::endl;

    // 发送响应
    std::string response = "Hello from server!";
    send(clientSocket, response.c_str(), response.length(), 0);
    } else {
    std::cerr << "Receive failed." << std::endl;
    }

    // 关闭套接字
    closesocket(clientSocket);
    closesocket(listenSocket);
    WSACleanup();

    return 0;
    }

    客户端代码

    #include <winsock2.h>
    #include <iostream>
    #include <string>

    #pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库

    // 客户端
    int main() {
    WSADATA wsaData;
    SOCKET clientSocket;
    sockaddr_in serverAddr;
    char sendBuffer[512], recvBuffer[512];

    // 初始化 Winsock 库
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
    std::cerr << "Winsock initialization failed." << std::endl;
    return 1;
    }

    // 创建客户端套接字
    clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (clientSocket == INVALID_SOCKET) {
    std::cerr << "Socket creation failed." << std::endl;
    WSACleanup();
    return 1;
    }

    // 设置服务器地址
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8080); // 设置端口
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器 IP 地址

    // 连接到服务器
    if (connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
    std::cerr << "Connection failed." << std::endl;
    closesocket(clientSocket);
    WSACleanup();
    return 1;
    }

    std::cout << "Connected to server!" << std::endl;

    // 发送数据
    std::string message = "Hello from client!";
    send(clientSocket, message.c_str(), message.length(), 0);

    // 接收响应
    int bytesReceived = recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);
    if (bytesReceived > 0) {
    recvBuffer[bytesReceived] = '\\0'; // 添加字符串结束符
    std::cout << "Received from server: " << recvBuffer << std::endl;
    } else {
    std::cerr << "Receive failed." << std::endl;
    }

    // 关闭套接字
    closesocket(clientSocket);
    WSACleanup();

    return 0;
    }

    代码解释

    服务器端代码:
  • 初始化 Winsock:通过调用 WSAStartup 来初始化 Winsock 库,准备进行网络操作。
  • 创建套接字:调用 socket 创建一个 TCP 套接字(SOCK_STREAM)。
  • 绑定地址:使用 bind 将套接字绑定到指定的端口 8080 上,这样客户端才能通过该端口连接。
  • 监听连接:通过 listen 函数监听客户端的连接请求,等待客户端连接。
  • 接收连接:使用 accept 函数接受客户端连接,一旦连接成功,服务器开始接收数据。
  • 接收数据并发送响应:使用 recv 接收客户端发送的数据,然后通过 send 向客户端发送响应。
  • 清理:关闭套接字,并调用 WSACleanup 清理 Winsock。
  • 客户端代码:
  • 初始化 Winsock:通过调用 WSAStartup 初始化 Winsock 库。
  • 创建套接字:通过 socket 创建一个 TCP 套接字。
  • 连接服务器:通过 connect 将客户端连接到服务器(IP 地址为 127.0.0.1,端口为 8080)。
  • 发送数据:使用 send 发送数据到服务器。
  • 接收响应:使用 recv 接收服务器的响应数据。
  • 清理:关闭套接字,并调用 WSACleanup 清理 Winsock。
  • 测试与运行

  • 运行服务器端:

    • 先运行服务器端程序,它将开始监听端口 8080。
  • 运行客户端:

    • 运行客户端程序,客户端会连接到本地服务器并发送消息。
    • 服务器接收到消息后会回复客户端,客户端接收服务器的响应并显示。
  • 示例输出

    • 服务器端(假设客户端发送消息 "Hello from client!"):

    Waiting for client connection…
    Client connected!
    Received from client: Hello from client!

    客户端(收到服务器的响应 "Hello from server!"):

    Connected to server!
    Received from server: Hello from server!

    总结

    通过这个项目,我们实现了一个简单的 TCP 网络通信程序,包含服务器端和客户端。通过使用 Winsock 库的基本功能,我们能够在 C++ 中创建一个 TCP 服务器并与客户端进行通信。此代码可以作为更复杂网络应用程序的基础。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » VC++实现++tcp网络通讯服务器+客户端(附带源码)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!