Linux网络部分——TCP协议服务端客户端交互接口,入门级硬核解析1.0

@bit::Shadow
✧(≖ ◡ ≖✿

目录

TCP与UDP差异

最核心差异

监听listen()

[listen 的直观理解(它在做什么?)](#listen 的直观理解(它在做什么?))

🔗listen错误时枚举的使用原理(区分与C是很有必要的)"C++进阶知识5.0"blog(待链接)

listen造成accept的诞生原理

accept正常返回的套接字(sockfd)与listensockfd的对比(了解)

TCP套接字的状态限定(待深入)

accept()

[1. 回顾 accept() 的函数原型](#1. 回顾 accept() 的函数原型)

[2. 为什么不需要初始化?因为它是"输出参数"](#2. 为什么不需要初始化?因为它是"输出参数")

[🔗netstat telnet使用(必看)blog](#🔗netstat telnet使用(必看)blog)

普通监视

🔗telnet的使用

链接前

链接

链接后

客户端

connect()客户向服务打电话☎️以求建立链接


TCP简易服务端客户端框架的搭建gitee(复习必看)

TCP与UDP差异

最核心差异

TCP是有状态有连接可靠 协议;UDP是无状态无连接不可靠协议;

对比维度 UDP(你用的 SOCK_DGRAM TCP(SOCK_STREAM
连接状态 无连接(发数据前不需握手) 面向连接(需三次握手建立连接)
可靠性 不可靠(丢包不重传,可能乱序) 可靠(确认重传、保证顺序)
数据边界 保留边界 (每次 sendto 对应一次 recvfrom 无边界(流式) (多次 send 可被一次 recv 读完)
传输效率 (头部开销小,无拥塞控制) (头部大,有流量/拥塞控制)
典型应用 DNS、视频直播、实时游戏、VoIP HTTP、FTP、SSH、邮件、数据库
Socket 类型 SOCK_DGRAM SOCK_STREAM
核心函数 sendto / recvfrom connect / accept / send / recv

监听listen()

listen 的直观理解(它在做什么?)

继续用我们之前的"打电话"比喻:

  • socket() 创建了一个"电话机"(创建套接字)。

  • bind() 给电话机绑定了号码(绑定 IP 和端口)。

  • listen() 则是把电话机切换到"响铃待机模式" 。它告诉操作系统内核:"我准备好了,现在开始监听这个端口,随时准备接听客户端的来电请求。"

在代码层面,它的函数原型通常是:

c

复制代码
int listen(int sockfd, int backlog);
  • sockfd:刚才创建的那个套接字。

  • backlog :这是最核心的参数,它限制了"全连接队列(Accept 队列)"的最大长度。(不宜过大、过小)

🔗listen错误时枚举的使用原理(区分与C是很有必要的)"C++进阶知识5.0"blog(待链接)

listen造成accept的诞生原理

使用端(使用listen的)原套接字状态改变!

在listen调用之前,TCP套接字处于主动状态。(即类似UDP的状态)

在listen调用之后,TCP套接字处于被动状态 ,只能接受信息**链接,**无法被用以发送信息。

因此我们常使用listen的套接字命名为"_listenSockfd"

匿名服务端应该怎样接受与发送信息?

答案是"accept"再创建sockfd(因此就引入了多线程,多进程等版本(单进程版本在实际工程中不存在!))

accept正常返回的套接字(sockfd)与listensockfd的对比(了解)

|-----------------|-----------------------------------------|-------------------------------|
| | 监听套接字(Listening Socket) | 已连接套接字(Connected Socket) |
| 创建时机 | socket() + bind() + listen() 后产生 | accept() 从全连接队列中取出后返回 |
| 身份 | "前台接待员" | "专属客服代表" |
| 职责 | 只负责监听新的连接请求(三次握手) | 只负责收发数据(读写业务数据) |
| 能否 write | 不能 (理论上强行写会报错 EPIPEENOTCONN) | (服务端通过它回复 HTTP 响应、文件数据等) |
| 数量 | 整个服务端通常只有 1 个 | 每个客户端连接对应 1 个,可能有成千上万个 |

TCP套接字的状态限定(待深入)

TCP是有严格状态机的。一个套接字在任意时刻只能处于一种状态:

套接字类型 TCP状态 允许的操作
主动套接字(客户端) CLOSEDSYN_SENTESTABLISHED 只能connect()发起连接,成功后收发数据
被动套接字(监听) CLOSEDLISTEN 只能accept()接收新连接,不能收发数据
已连接套接字(服务端) ESTABLISHEDCLOSE_WAIT → ... 只能read()/write()收发数据,不能accept()

accept()

阻塞等待对象链接。

1. 回顾 accept() 的函数原型

c

复制代码
int accept(int _listensockfd, struct sockaddr *addr, socklen_t *addrlen);
  • 第一个参数 :监听套接字(你已经listen()好的那个)。

  • 第二个参数struct sockaddr *addr ------ 这是一个"输出参数"

  • 第三个参数socklen_t *addrlen ------ 这是一个"输入输出参数"


2. 为什么不需要初始化?因为它是"输出参数"

在C语言中,函数参数有两种用途:

参数类型 方向 调用者要做的事 函数要做的事
输入参数 调用者 → 函数 填充好数据再传进去 读取并使用
输出参数 函数 → 调用者 分配好内存即可 往里面写数据
输入输出参数 双向 既要初始化,又要读取函数写回的值 既要读取,也要修改

accept()的第二个参数 addr 是一个典型的"输出参数"

  • 调用前 :你只需要提供一块足够大的内存struct sockaddr_instruct sockaddr_storage),里面的值无所谓,可以是随机垃圾。

  • 调用后 :内核会把客户端的IP地址和端口号填进这个结构体,然后返回给你。

🔗netstat telnet使用(必看)blog

普通监视

部分进程PID隐藏(权限不足、可使用sudo提权)

bash 复制代码
w@instance-qhw6x01g:~/e2026/Auguest/TCPServerClient/build$ netstat -tanp | grep LISTEN
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:45825         0.0.0.0:*               LISTEN      10811/node          
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      72312/./tcpServer   
tcp        0      0 127.0.0.1:43557         0.0.0.0:*               LISTEN      10587/code-a5b50095 
tcp        0      0 127.0.0.1:36239         0.0.0.0:*               LISTEN      10558/code-a5b50095 
tcp        0      0 0.0.0.0:428             0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:35897         0.0.0.0:*               LISTEN      9347/code-df53daabb 
tcp6       0      0 :::781                  :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   
tcp6       0      0 ::1:6010                :::*                    LISTEN      -    

sudo提权

bash 复制代码
w@instance-qhw6x01g:~/e2026/Auguest/TCPServerClient/build$ sudo netstat -tanp | grep LISTEN
[sudo] password for w: 
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      730/systemd-resolve 
tcp        0      0 127.0.0.1:45825         0.0.0.0:*               LISTEN      10811/node          
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      72588/sshd: w@pts/0 
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      72312/./tcpServer   
tcp        0      0 127.0.0.1:43557         0.0.0.0:*               LISTEN      10587/code-a5b50095 
tcp        0      0 127.0.0.1:36239         0.0.0.0:*               LISTEN      10558/code-a5b50095 
tcp        0      0 0.0.0.0:428             0.0.0.0:*               LISTEN      2793/has_agent      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      4337/sshd: /usr/sbi 
tcp        0      0 127.0.0.1:35897         0.0.0.0:*               LISTEN      9347/code-df53daabb 
tcp6       0      0 :::781                  :::*                    LISTEN      1037/./bcm-agent    
tcp6       0      0 :::22                   :::*                    LISTEN      4337/sshd: /usr/sbi 
tcp6       0      0 ::1:6010                :::*                    LISTEN      72588/sshd: w@pts/0 

🔗telnet的使用

你应该仔细观看动态的变化(待补充)

链接前

链接

链接后


客户端

connect()客户向服务打电话☎️以求建立链接

cpp 复制代码
#include<sys/socket.h>

int connect(int sockfd, const sockaddr* __addr, socklen_t len);

|--------|----------------|-------|
| 参数 | 含义 | 方向 |
| sockfd | 客户端创建的套接字 | 一般输入型 |
| _addr | 服务端的IP与端口号 | 输入型参数 |
| len | 结构体大小 | 输入型参数 |

返回值

  • 成功:返回 0

  • 失败:返回 -1,并设置 errno

感谢支持,长期连载

欢迎关注

相关推荐
2601_953988071 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·后端·物联网·tcp/ip·数学建模·前端框架
Forever Nore1 小时前
LeetCode 14 最长公共前缀 - 纵向扫描
linux·服务器·leetcode
拂拉氏1 小时前
【知识讲解】 Linux权限相关知识讲解
linux·权限
小新讲网安2 小时前
HTTP请求走私攻击实战:CL.TE与TE.CL绕过前端服务器全解析
服务器·前端·网络·web安全·http·架构·漏洞
桑榆4166 小时前
双系统(Windows + Ubuntu)安装流程
linux·windows·ubuntu
ltl13 小时前
实时 OS 巡礼:VxWorks、QNX、Zephyr 与 PREEMPT_RT
linux
我是谁??13 小时前
Ubuntu22.04更换清华源
linux·运维·服务器
上海安当技术13 小时前
固件签名与Secure Boot:安当CAS如何构建汽车固件信任链
网络·汽车·信任链·boot·secure·固件签名·安当cas
上海安当技术14 小时前
诊断接入认证:安当CAS如何堵住汽车网络安全的物理后门
网络·web安全·汽车·access·secure·安当cas·诊断接入认证