Linux——TCP通信

目录

TCP通信

TcpServer.cc

TcpClient.cc

​编辑

总结

TCP协议的特点

UDP协议的特点


只有认知的突破 💫才能带来真正的成长 💫编程技术的学习 💫没有捷径 💫一起加油💫

🍁感谢各位的观看 🍁欢迎大家留言 🍁咱们一起加油 🍁努力成为更好的自己🍁

TCP通信

客户端:创建socket套接字------>connect建立链接------>sendto通信

服务端:创建socket套接字------>bind绑定------>listen监听------>accept接收请求

connect()和accept()函数都是阻塞式函数。

TcpServer.cc
cpp 复制代码
#include <iostream>
#include <cstring>
// Linux网络编程核心头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

using namespace std;

// 配置常量:监听端口、缓冲区大小(可自定义)
const int PORT = 8888;
const int BUF_SIZE = 1024;

int main() {
    // 1. 创建TCP socket:AF_INET(IPv4)、SOCK_STREAM(TCP)、0(默认协议)
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd < 0) {
        perror("socket create failed"); // 打印系统错误信息
        return -1;
    }

    // 2. 配置服务端地址结构
    sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr)); // 初始化地址内存
    server_addr.sin_family = AF_INET;             // IPv4协议
    server_addr.sin_addr.s_addr = INADDR_ANY;     // 监听本机所有网卡IP
    server_addr.sin_port = htons(PORT);           // 端口转网络字节序(大端)

    // 3. 绑定socket与IP+端口
    if (bind(server_fd, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("bind failed");
        close(server_fd);
        return -1;
    }

    // 4. 开始监听:第二个参数为半连接队列大小(极简版设为5即可)
    if (listen(server_fd, 5) < 0) {
        perror("listen failed");
        close(server_fd);
        return -1;
    }
    cout << "服务端启动成功,监听端口:" << PORT << ",等待客户端连接..." << endl;

    // 5. 接受客户端连接(阻塞式,直到有客户端连接)
    sockaddr_in client_addr; // 存储客户端的地址信息
    socklen_t client_addr_len = sizeof(client_addr);
    int conn_fd = accept(server_fd, (sockaddr*)&client_addr, &client_addr_len);
    if (conn_fd < 0) {
        perror("accept failed");
        close(server_fd);
        return -1;
    }
    // 打印连接的客户端信息(IP+端口)
    cout << "客户端连接成功:IP=" << inet_ntoa(client_addr.sin_addr)
         << ",Port=" << ntohs(client_addr.sin_port) << endl;

    // 6. 读写数据:接收客户端消息并原内容回显
    char buf[BUF_SIZE] = {0};
    ssize_t recv_len = recv(conn_fd, buf, BUF_SIZE-1, 0); // 接收数据,保留1位存'\0'
    if (recv_len < 0) {
        perror("recv failed");
        close(conn_fd);
        close(server_fd);
        return -1;
    } else if (recv_len == 0) {
        cout << "客户端主动关闭连接" << endl;
        close(conn_fd);
        close(server_fd);
        return 0;
    }
    cout << "收到客户端消息:" << buf << endl;

    // 回显消息给客户端
    send(conn_fd, buf, strlen(buf), 0);
    cout << "消息已回显给客户端" << endl;

    // 7. 关闭文件描述符(Linux中socket是特殊文件描述符)
    close(conn_fd);   // 关闭与客户端的连接
    close(server_fd); // 关闭服务端监听socket
    return 0;
}
TcpClient.cc
cpp 复制代码
#include <iostream>
#include <cstring>
// Linux网络编程核心头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

using namespace std;

// 配置常量:服务端IP(本机测试用127.0.0.1)、服务端端口、缓冲区大小
const char* SERVER_IP = "127.0.0.1";
const int SERVER_PORT = 8888;
const int BUF_SIZE = 1024;

int main() {
    // 1. 创建TCP socket(与服务端一致)
    int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd < 0) {
        perror("socket create failed");
        return -1;
    }

    // 2. 配置服务端地址结构(用于指定连接目标)
    sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    // 将服务端IP字符串转为网络字节序的32位整数
    if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
        perror("inet_pton failed (IP格式错误)");
        close(client_fd);
        return -1;
    }

    // 3. 连接服务端(阻塞式,直到连接成功或失败)
    if (connect(client_fd, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("connect failed(请检查服务端是否启动/IP+端口是否正确)");
        close(client_fd);
        return -1;
    }
    cout << "成功连接服务端:" << SERVER_IP << ":" << SERVER_PORT << endl;

    // 4. 发送消息给服务端
    char send_buf[BUF_SIZE] = {0};
    cout << "请输入要发送的消息:";
    cin >> send_buf; // 简单读取字符串(无空格,如需空格用cin.getline)
    send(client_fd, send_buf, strlen(send_buf), 0);
    cout << "消息已发送给服务端:" << send_buf << endl;

    // 5. 接收服务端回显的消息
    char recv_buf[BUF_SIZE] = {0};
    ssize_t recv_len = recv(client_fd, recv_buf, BUF_SIZE-1, 0);
    if (recv_len < 0) {
        perror("recv failed");
        close(client_fd);
        return -1;
    }
    cout << "收到服务端回显消息:" << recv_buf << endl;

    // 6. 关闭socket文件描述符
    close(client_fd);
    return 0;
}

总结

TCP协议的特点
  • 传输层协议

  • 有连接

  • 可靠传输

  • 面向字节流

UDP协议的特点
  • 传输层协议

  • 无连接

  • 不可靠传输

  • 面向数据报

相关推荐
开开心心就好2 小时前
小巧绿色免费关机工具,支持定时倒计时
linux·运维·服务器·安全·powerpoint·1024程序员节·foxmail
卢傢蕊2 小时前
LNAMP 网站架构与部署
运维·nginx·lamp
linux修理工2 小时前
下载亚马逊Corretto 17的方法(OpenJDK 17发行版)
java·运维·服务器
gbling2 小时前
网页多次重定向问题
运维·nginx
Xi-Xu2 小时前
在云服务器上安全运行 OpenClaw:从安装到加固的完整指南
运维·服务器·人工智能·安全
孫治AllenSun3 小时前
【Linux】配置服务自启动
linux·运维·服务器
小生不才yz3 小时前
【Makefile 专家之路 | 基础篇】03. 规矩方圆:书写规则详解(通配符、文件搜索与伪目标)
linux
tang777893 小时前
哪些行业用动态代理ip?哪些行业用静态代理IP?怎样区分动态ip和静态ip?(互联网人必码·实用长文)
大数据·网络·爬虫·python·网络协议·tcp/ip·智能路由器
Lueeee.3 小时前
Linux下的ULN2003驱动板与28BYJ-48步进电机驱动移植
linux·驱动开发