Socket函数详解

一、先理解一个核心概念

在 Linux 中:
Socket 本质上是一个文件描述符(fd)

所以它和文件一样:

1、用一个整数表示

2、用 read/write 思想操作

3、最后要 close()

二、头文件分别是干什么的

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

提供:

socket()

bind()

listen()

accept()

send()

recv()

cpp 复制代码
#include <netinet/in.h>

提供:

sockaddr_in(IPv4地址结构)

端口、IP相关定义

cpp 复制代码
#include <arpa/inet.h>

提供:
IP字符串转换函数:

inet_pton()(字符串 → 二进制)

inet_ntop()(二进制 → 字符串)
字节序转换:

htons()、htonl()

ntohs()、ntohl()

cpp 复制代码
#include <unistd.h>

提供:

close()

三、socket() ------ 创建通信端点

函数:

cpp 复制代码
int socket(int domain, int type, int protocol);

参数解释:
1. domain(地址族)常用AF_INET

2. type(协议类型)

TCP 必须用:
SOCK_STREAM

3. protocol

一般写:0

系统自动选择 TCP 或 UDP。

返回值:

fd >= 0 成功

fd == -1 失败

四、bind() ------ 给socket分配地址

cpp 复制代码
int bind(int fd, const sockaddr *addr, socklen_t len);

作用:

告诉系统:这个socket用哪个IP和端口

地址结构(IPv4)

sockaddr_in addr;

addr.sin_family = AF_INET;

addr.sin_port = htons(8080);

addr.sin_addr.s_addr = htonl(INADDR_ANY);

为什么要 htons?

因为:网络统一使用 大端序

五、listen() ------ 进入监听状态

cpp 复制代码
int listen(int fd, int backlog);

作用:

告诉系统:我这个socket是服务器,要等待客户端连接

参数:

backlog = 等待队列长度

例如:

listen(fd, 5);

最多排队5个未处理连接。

六、accept() ------ 接受连接(关键)

cpp 复制代码
int accept(int fd, sockaddr *client, socklen_t *len);

作用:

从等待队列中取出一个客户端连接

重要理解:

socket() 创建的是 监听socket

accept() 返回的是 新的连接socket

所以:

listen_fd ------ 用来监听

conn_fd ------ 用来通信

七、connect() ------ 客户端发起连接

cpp 复制代码
int connect(int fd, sockaddr *server, len);

作用:

向服务器发起TCP三次握手

成功后:

fd 就变成一个已连接socket

八、send() ------ 发送数据

cpp 复制代码
ssize_t send(int fd, const void *buf, size_t len, int flags);


返回值:

大于0 实际发送字节数

0 对方关闭

-1 错误

注意:

TCP 可能 没有一次发送完,要循环发送。

九、recv() ------ 接收数据

cpp 复制代码
ssize_t recv(int fd, void *buf, size_t len, int flags);


TCP 是字节流

一次recv不一定是完整消息

十、close() ------ 关闭socket

cpp 复制代码
close(fd);

作用:

1、释放资源

2、发送 FIN,关闭TCP连接

十一、完整流程图(非常重要)
服务器

复制代码
socket()
   ↓
bind()
   ↓
listen()
   ↓
accept()
   ↓
send()/recv()
   ↓
close()

客户端

复制代码
socket()
   ↓
connect()
   ↓
send()/recv()
   ↓
close()

十二、一个底层理解(系统角度)

当客户端连接时:

复制代码
客户端 socket
        ⇅
   TCP三次握手
        ⇅
服务器 accept() 返回 conn_fd

系统内核维护:

1、发送缓冲区

2、接收缓冲区

3、重传机制

4、拥塞控制

应用层只负责:

复制代码
send / recv
相关推荐
xlp666hub5 小时前
Leetcode第七题:用C++解决接雨水问题
c++·leetcode
肆忆_6 小时前
实战复盘:手写 C++ 虚拟机的高性能并行 GC (Thread Pool + Work Stealing)
c++
肆忆_6 小时前
虚函数进阶答疑:把上一篇博客评论区里最容易卡住的问题,一次追到底
c++
saltymilk1 天前
使用 C++ 模拟 ShaderLanguage 的 swizzle
c++·模板元编程
xlp666hub1 天前
Leetcode第五题:用C++解决盛最多水的容器问题
linux·c++·leetcode
得物技术1 天前
搜索 C++ 引擎回归能力建设:从自测到工程化准出|得物技术
c++·后端·测试
xlp666hub2 天前
Leetcode 第三题:用C++解决最长连续序列
c++·leetcode
会员源码网2 天前
构造函数抛出异常:C++对象部分初始化的陷阱与应对策略
c++
xlp666hub2 天前
Leetcode第二题:用 C++ 解决字母异位词分组
c++·leetcode
Qinana2 天前
从数据包旅程到首屏渲染:深入理解 TCP/IP 如何决定你的 Web 性能
前端·tcp/ip·浏览器