MST
星途 面试题库

面试题:C++网络编程之TCP连接实现

在C++中,使用socket进行TCP网络编程,描述实现一个简单的客户端与服务器端建立连接并进行数据传输的基本步骤,并给出关键代码片段。
26.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

服务器端基本步骤

  1. 创建套接字:使用 socket 函数创建一个套接字,指定协议族为 AF_INET(IPv4),套接字类型为 SOCK_STREAM(TCP)。
  2. 绑定地址:使用 bind 函数将套接字与本地地址和端口号绑定。
  3. 监听连接:使用 listen 函数将套接字设置为监听模式,等待客户端连接。
  4. 接受连接:使用 accept 函数接受客户端的连接请求,返回一个新的套接字用于与客户端通信。
  5. 数据传输:使用 sendrecv 函数在新的套接字上进行数据传输。
  6. 关闭套接字:通信结束后,使用 close 函数关闭套接字。

服务器端关键代码片段

#include <iostream>
#include <winsock2.h> // Windows下需要包含此头文件,Linux下为<sys/socket.h>等
#pragma comment(lib, "ws2_32.lib") // Windows下链接ws2_32库

int main() {
    // 初始化Winsock(Windows下)
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

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

    // 绑定地址
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(12345); // 端口号
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    if (bind(listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "Bind failed" << std::endl;
        closesocket(listenSocket);
        WSACleanup();
        return 1;
    }

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

    std::cout << "Waiting for a connection..." << std::endl;

    // 接受连接
    sockaddr_in clientAddr;
    int clientAddrLen = sizeof(clientAddr);
    SOCKET clientSocket = accept(listenSocket, (sockaddr*)&clientAddr, &clientAddrLen);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "Accept failed" << std::endl;
        closesocket(listenSocket);
        WSACleanup();
        return 1;
    }

    // 数据传输
    char buffer[1024];
    int bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0);
    if (bytesReceived > 0) {
        buffer[bytesReceived] = '\0';
        std::cout << "Received: " << buffer << std::endl;
    }

    const char* response = "Message received successfully";
    send(clientSocket, response, strlen(response), 0);

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

客户端基本步骤

  1. 创建套接字:同服务器端,使用 socket 函数创建一个套接字。
  2. 连接服务器:使用 connect 函数连接到服务器的地址和端口。
  3. 数据传输:使用 sendrecv 函数进行数据传输。
  4. 关闭套接字:通信结束后,关闭套接字。

客户端关键代码片段

#include <iostream>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

int main() {
    // 初始化Winsock
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    // 创建套接字
    SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "Socket creation failed" << std::endl;
        return 1;
    }

    // 连接服务器
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(12345);
    inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr); // 服务器IP地址
    if (connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "Connect failed" << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    // 数据传输
    const char* message = "Hello, server!";
    send(clientSocket, message, strlen(message), 0);

    char buffer[1024];
    int bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0);
    if (bytesReceived > 0) {
        buffer[bytesReceived] = '\0';
        std::cout << "Received: " << buffer << std::endl;
    }

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

请注意,上述代码在Windows环境下编写,使用了Windows Sockets(Winsock)API。在Linux环境下,需要修改头文件和部分函数名(如 closesocket 改为 closeWSAStartupWSACleanup 等函数不存在),并且链接不同的库。同时,实际应用中还需要更多的错误处理和优化。