多机TCP通讯之hello world(C++)

文章目录

TCP是什么

TCP(传输控制协议)是一种在计算机网络中广泛使用的协议,它提供了可靠的、面向连接的数据传输服务。TCP 是 OSI 模型中的传输层协议,它确保了数据的可靠性、顺序性和流控制。

以下是 TCP 通讯的一些关键特点和概念:

  • 可靠性: TCP 提供可靠的数据传输。它使用确认机制,确保数据的每个部分都已被成功接收,如果数据在传输中出现错误或丢失,TCP 将负责重新传输。

  • 面向连接: TCP 是一种面向连接的协议。在进行数据传输之前,必须先建立连接。连接的建立和终止都需要一些握手和挥手的过程,以确保双方都已准备好进行通信。

  • 全双工通信: TCP 支持全双工通信,即双方可以同时发送和接收数据。这使得双方能够在同一时间内进行双向的通信。

  • 流控制: TCP 使用窗口控制机制来进行流量控制。这确保了在通信双方之间合适的速率上进行数据传输,防止发送方发送过多数据导致接收方无法处理。

  • 顺序性: TCP 保证传输的数据按照发送的顺序到达接收端。即使在网络中出现乱序的情况,TCP 会重新排序数据,以确保按照正确的顺序进行处理。

  • 连接管理: TCP 提供连接的建立、维护和释放。连接的建立和释放过程中包含握手和挥手的步骤,以确保通信的可靠性和一致性。

  • 端口和套接字: 在 TCP 通信中,通信的双方通过端口和套接字进行标识。端口用于标识特定的应用程序,而套接字则表示在网络中的通信端点。

  • 可靠的错误检测和重传机制: TCP 使用序号和确认号来确保数据的可靠传输。如果发送方没有收到确认,它将会重新发送数据。

总体而言,TCP 是一种适用于可靠、有序、面向连接的数据传输的协议。它适用于需要确保数据完整性的应用场景,如文件传输、网页浏览、电子邮件等。然而,由于其一些额外的开销和复杂性,对于一些实时性要求较高的应用,可能会选择使用UDP等协议。

准备工作

  • 打开防火墙: sudo ufw enable
  • 打开目标端口:例如打开22端口sudo ufw allow 22
  • 测试前,ping一下,看连接是或否成功。

两端的通讯流程

CMakeLists.txt

cpp 复制代码
cmake_minimum_required(VERSION 3.18)
project(ExampleProgram)

set(CMAKE_CXX_STANDARD 11)


add_executable(tcp-client tcp-client.cpp)
add_executable(tcp-server tcp-server.cpp)


# Add -lpthread
target_link_libraries(tcp-client pthread)
target_link_libraries(tcp-server pthread)

服务端代码

cpp 复制代码
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int main() {
    // 创建服务器套接字
    int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1) {
        std::cerr << "Failed to create server socket." << std::endl;
        return 1;
    }

    // 设置服务器地址结构
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(8080); // 服务器监听的端口号

    // 绑定套接字
    if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
        std::cerr << "Bind failed." << std::endl;
        close(serverSocket);
        return 1;
    }

    // 监听连接
    if (listen(serverSocket, SOMAXCONN) == -1) {
        std::cerr << "Listen failed." << std::endl;
        close(serverSocket);
        return 1;
    }

    std::cout << "Server is listening for incoming connections..." << std::endl;

    while (true) {
        // 接受连接
        int clientSocket = accept(serverSocket, NULL, NULL);
        if (clientSocket == -1) {
            std::cerr << "Accept failed." << std::endl;
            close(serverSocket);
            return 1;
        }

        std::cout << "Connection established with a client." << std::endl;

        // 发送消息给客户端
        const char* message = "Hello from server!";
        if (send(clientSocket, message, strlen(message), 0) == -1) {
            std::cerr << "Error sending message." << std::endl;
        }

        // 关闭客户端套接字
        close(clientSocket);
    }

    // 服务器永远不会执行到这里,但可以加上关闭服务器套接字的代码
    close(serverSocket);

    return 0;
}

客户端代码

cpp 复制代码
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int main() {
    while (true) {
        // 创建客户端套接字
        int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
        if (clientSocket == -1) {
            std::cerr << "Failed to create client socket." << std::endl;
            return 1;
        }

        // 设置服务器地址结构
        sockaddr_in serverAddr;
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_addr.s_addr = inet_addr("192.168.110.83"); // 服务器的 IP 地址
        serverAddr.sin_port = htons(8080); // 服务器监听的端口号

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

        std::cout << "Connected to the server." << std::endl;

        // 接收消息
        char buffer[256];
        memset(buffer, 0, sizeof(buffer));
        if (recv(clientSocket, buffer, sizeof(buffer), 0) == -1) {
            std::cerr << "Error receiving message." << std::endl;
        } else {
            std::cout << "Received message from server: " << buffer << std::endl;
        }

        // 关闭客户端套接字
        close(clientSocket);

        // 在这里可以添加一些延时,以避免过于频繁地连接服务器
        sleep(1);
    }

    return 0;
}

参考

https://blog.csdn.net/cyj_001/article/details/131782022
https://www.bilibili.com/video/BV1ne411A7hP/?spm_id_from=333.337.search-card.all.click&vd_source=667c3d14dbb51ec849c0bc7c38329d10

相关推荐
步行cgn3 小时前
HTTP 常用请求方法详解
网络·网络协议·http
mengge.cloud4 小时前
1019Namespace ,Contexts ,Kubernetes Pod
运维·服务器·网络·云原生·容器·kubernetes·云计算
艾iYYY4 小时前
【无标题】
linux·开发语言·网络·操作系统
QZ166560951594 小时前
可视化易用·低误报率·跨区域部署:知源-AI数据分类分级系统在金融行业的落地实践
大数据·网络·安全·网络安全
aixingkong9214 小时前
UALink 技术白皮书解读
服务器·网络·硬件架构
Amumu121385 小时前
Node学习: 网络基础概念 + HTTP模块
网络·node.js
tdtengrun5 小时前
“绿色轮胎安全周”走进校园,让安全与环保理念扎根童心
网络·媒体
Android小码家6 小时前
Vehicle 实战 自定义属性+测试demo
java·c++·framework·vhal·vehicle
hetao17338376 小时前
2026-10-19 hetao1733837 的刷题记录
c++·算法
夏虫不可与之言冰6 小时前
第三课 点亮 LED 与定时器非阻塞闪烁
c语言·c++·vscode·单片机·嵌入式硬件·物联网