[网络] [TCP] Linux TCP Socket 学习指南

news/2025/10/26 0:14:04/文章来源:https://www.cnblogs.com/migrator/p/19166171
[网络] [TCP] Linux TCP Socket 学习指南

ChatGPT生成(2025年10月26日00:08:46)

🧠 Linux TCP Socket 学习指南

📘 一、什么是 TCP Socket?

1. TCP 与 Socket 的关系

  • TCP(Transmission Control Protocol):传输控制协议,提供可靠、面向连接的字节流通信。
  • Socket(套接字):是操作系统提供的一种编程接口,让程序员能使用 TCP/IP 协议进行通信。

简单来说:

Socket 就像是“网络中的文件句柄”,你可以用它来“读写”网络数据。

在 Linux 中,一切皆文件,Socket 也是一种特殊文件,你可以:

read() / write() / send() / recv() / close()

🧩 二、Socket 的创建与通信流程

我们以 TCP 为例,整个过程就像打电话:

阶段 客户端 服务端
创建套接字 socket() socket()
绑定地址 —— bind()
监听连接 —— listen()
连接请求 connect() accept()
数据传输 send()/recv() send()/recv()
断开连接 close() close()

🧱 三、服务端与客户端基本代码结构

✅ 服务端示例(server.c)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>int main() {int server_fd, client_fd;struct sockaddr_in server_addr, client_addr;socklen_t addr_len = sizeof(client_addr);char buffer[1024];// 1. 创建Socketserver_fd = socket(AF_INET, SOCK_STREAM, 0);if (server_fd < 0) {perror("socket error");exit(1);}// 2. 绑定地址和端口server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡server_addr.sin_port = htons(5000);       // 端口号if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {perror("bind error");exit(1);}// 3. 监听连接请求listen(server_fd, 5);printf("Server listening on port 5000...\n");// 4. 接受连接client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_len);printf("Client connected: %s\n", inet_ntoa(client_addr.sin_addr));// 5. 通信recv(client_fd, buffer, sizeof(buffer), 0);printf("Received: %s\n", buffer);send(client_fd, "Hello from server", 18, 0);// 6. 关闭close(client_fd);close(server_fd);return 0;
}

✅ 客户端示例(client.c)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>int main() {int sock;struct sockaddr_in server_addr;char buffer[1024];// 1. 创建Socketsock = socket(AF_INET, SOCK_STREAM, 0);// 2. 服务器地址server_addr.sin_family = AF_INET;server_addr.sin_port = htons(5000);inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);// 3. 连接服务器connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));// 4. 发送/接收数据send(sock, "Hello Server", 12, 0);recv(sock, buffer, sizeof(buffer), 0);printf("From Server: %s\n", buffer);// 5. 关闭close(sock);return 0;
}

编译运行:

gcc server.c -o server
gcc client.c -o client
./server
# 另一个终端:
./client

⚙️ 四、Socket 常用函数讲解

函数名 作用 关键参数说明
socket() 创建套接字 AF_INET(IPv4), SOCK_STREAM(TCP)
bind() 绑定IP和端口 通常服务端用
listen() 开始监听 参数是最大等待队列长度
accept() 等待客户端连接 返回新的连接套接字
connect() 连接到服务器 客户端使用
send() / recv() 发送/接收数据 支持 flags 参数
close() 关闭连接 释放资源

📦 五、TCP Socket 常见选项与参数

1. setsockopt() / getsockopt()

用来设置或获取 Socket 选项。
原型:

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

2. 常见 TCP 参数

选项名 说明 示例
SO_REUSEADDR 允许端口重用 可避免 "Address already in use"
TCP_NODELAY 禁用 Nagle 算法(减少延迟) 对实时性要求高的应用使用
SO_RCVBUF / SO_SNDBUF 设置接收/发送缓冲区大小 优化性能
SO_KEEPALIVE TCP 保活检测 检测长连接是否断开

示例:

int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

🧮 六、TCP 状态机与三次握手

🔁 三次握手过程

  1. 客户端 → SYN → 服务端
    请求建立连接。
  2. 服务端 → SYN + ACK → 客户端
    同意连接并回应。
  3. 客户端 → ACK → 服务端
    确认收到,连接建立完成。

此时双方可以开始通信。

🔚 四次挥手

断开连接时的过程:

  1. 客户端发送 FIN
  2. 服务端回 ACK
  3. 服务端再发 FIN
  4. 客户端回 ACK

🔍 七、常见 Socket 调试命令

命令 功能
netstat -anp 查看所有端口状态
ss -tulnp 查看TCP监听情况
lsof -i :5000 查看哪个进程占用端口
tcpdump -i eth0 port 5000 抓包分析 TCP 通信

📖 八、实践建议

  1. 从本地回环(127.0.0.1)开始实验。
  2. 尝试修改 SO_RCVBUF,观察传输速度。
  3. 使用 tcpdump 抓包,理解 TCP 三次握手。
  4. 了解非阻塞 I/O 和多路复用(select / poll / epoll)。

🎯 九、进阶方向(学习路线)

  1. 初级:

    • TCP/UDP Socket 基础编程
    • 多线程/多进程并发服务器
  2. 中级:

    • select / epoll 异步 I/O
    • TCP 参数调优、零拷贝
  3. 高级:

    • HTTP/HTTPS 协议实现
    • QUIC、TLS、安全传输层
    • 高性能服务器架构(如 Nginx、Redis)

💡 十、参考资料

  • 《Unix 网络编程(卷1)》—— W. Richard Stevens

  • man 手册:

    man 2 socket
    man 2 bind
    man 2 connect
    man 7 tcp
    
  • Linux 文档路径: /usr/include/linux/tcp.h

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/946522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[网络] [TCP] Linux UDP Socket 学习指南

[网络] [TCP] Linux UDP Socket 学习指南$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");📘 Linux UDP Socket 学习指南适合初学者理解 UDP 原理与在 Linu…

用户上下文透传机制详解

RuoYi-Cloud 用户上下文透传机制详解 引言 在微服务架构中,用户上下文的传递是一个关键问题。当一个请求在多个微服务之间调用时,如何确保用户身份信息能够正确传递到每个服务中,是实现安全认证和权限控制的基础。R…

品牌故事不会写?这个AI指令可能帮你解决大问题

本文分享了一个专业的品牌故事生成AI指令,帮助创业者和品牌负责人解决品牌叙事难题。文章提供了基础版和进阶版两个完整指令模板,通过结构化的方式指导AI生成具有情感共鸣和传播价值的品牌故事。内容包含实际使用案例…

电梯调度编程结对项目总结

电梯调度编程结对项目总结 项目地址:https://gitee.com/surrealgit/elevator_surreal.git 一、项目背景 本次课程大作业要求我们以结对编程的形式,完成一个电梯调度算法系统,包括调度算法设计、可视化界面实现、模块…

GuessGame两个版本的区别

GuessGame 两个版本的区别分析目录GuessGame 两个版本的区别分析一、控制台输出二、图形界面2.1 抽象类的好处三、两者对比四、总结 一、控制台输出 控制台版本的ConsoleGame是最基础、最传统的程序交互方式,它通过标…

第二次作业--田佳吉

https://gitee.com/tian-jiaji/qunqing.git

电脑频繁卡顿?4个CMD命令揪出后台隐藏进程

电脑频繁卡顿?4个CMD命令揪出后台隐藏进程电脑频繁卡顿?4个CMD命令揪出后台隐藏进程 你以为电脑卡顿只是垃圾太多?警惕!70%的后台异常进程都藏着“数字内鬼”——可能是黑客植入的隐蔽程序,正偷偷上传你的代码、文…

Graphiti:为智能体构建实时知识图谱,引领更聪明的 AI 时代

我一直觉得很神奇:大多数 AI 系统只要你一停止和它们对话,就会把一切都忘光。你喂给它们 facts、context、chat logs——会话一结束,噗的一下,全没了。这一直是“intelligent” agents 的最大瓶颈。 后来我发现了 …

2025_软件工程师课程辅导

第一周 课程内容 核心教学内容 App Inventor入门实践 使用工具App Inventor网站:http://ai2.17coding.net/AI伴侣手机应用应用相关素材从百度网盘下载上述工具软件和应用素材,如下图所示:课程案例Hello,小蜜蜂!画…

初学Claude Skills/Agents/Plugins功能

初学Claude Skills/Agents/Plugins功能目录SkillsSkills 的关键特点Skills的结构建立不同的 Skills个人 Skills项目 Skills插件 Skills编写 SKILL创建SKILL.md 文件Skills 如何工作学习网址AgentsPlugins Anthropic 刚…

《《《es相关

es 修改思路 一:新建索引 1.新建立索引 addIndex 为ik_smart 二: es 查询 1.es分页是从0开始.分页开始页-1,和结束页-1 2.addIndex 为 ik_smart(分词没有那么细,一般情况可以用这个)每天多努力一点,你将会变得更…

人资新手必看,企业绩效的意义

绩效考核管理是牵引整个企业行动方向的关键 其意义在于: 一、是有利于人事决策,通过绩效考核识别核心人才,对其加以培训、委以重任,同时能够根据员工特长决定人员调配和升降。 二、是确定合理的薪酬水平。根据员工的…

初学Claude Skills Agents功能

初学Claude Skills Agents功能目录SkillsSkills 的关键特点Skills的结构建立不同的 Skills个人 Skills项目 Skills插件 Skills编写 SKILL创建SKILL.md 文件Skills 如何工作学习网址Agents Anthropic 刚刚为 Claude 推出…

题解:P14309 【MX-S8-T2】配对

前言:考场上看出来了某关键性质结果发现做不下去了,然后就寄了。最后因为代码全部加了文件操作荣获总分 0 分的优异成绩。这种题需要我们多加猜测性质并辅以证明。 性质 #1 我们先不考虑任何修改操作。 一个子树内的…

HuggingFace 库使用小技巧

有时在处理数据的时候,我们在数据处理函数内部添加调试语句但是却没有输出,这可能是因为:数据被缓存了,令overwrite_cache: true即可,这样就会重新调用数据处理函数处理数据(一般在调试的时候使用)

【ArcMap】复制选中的线并将其上移一段距离

首先选中需要复制的线 在python2窗口中输入以下代码:此处为上移10米对于地理坐标系,使用0.00009度(约10米)对于投影坐标系,使用10米# -*- coding: utf-8 -*- import arcpy import os import sys# 重新加载sys并设…

启动分布式mapreduce的过程以及prompt

打开docker desktop,启动5个节点 用VS Code连接到第一个节点 为每个节点打开SSH服务service ssh start 每个节点运行cd /usr/local/hadoop-3.4.0/sbin && ./stop-all.sh && rm -rf /usr/local/hadoop…

记一次thinkphp3.2项目迁移失败的原因。 is currently unable to handle this request. HTTP ERROR 500

项目迁移到别的服务器后报错如下 This page isn’t working xxxx is currently unable to handle this request. HTTP ERROR 500这个问题是关闭了错误显示,不能看到明显的错误 打开php.ini文件 display_errors = Off …

20232310 2025-2026-1 《网络与系统攻防技术》实验三实验报告

1.实验内容 1.1回答问题 (1)杀软是如何检测出恶意代码的? 将文件二进制代码与病毒库中的已知恶意特征对比,若匹配则判定为威胁。 分析代码结构和行为逻辑,例如检查是否调用危险API、是否存在异常注册表操作或加密…

题解:AT_apc001_h Generalized Insertion Sort

为数不多能瞎搓出来的构造。 题意:给出一棵以 \(0\) 为根的树和每个点上的值 \(a_i\),每次可以对一个点 \(u\) 进行以下操作:设从根往下走到 \(u\) 的路径为 \(p_1,p_2,\cdots p_k\),那么令 \(a_{p_i}\leftarrow a…