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
相关推荐
代码改善世界19 小时前
【C++进阶】二叉搜索树
java·数据结构·c++
春蕾夏荷_72829772519 小时前
c++ 编译abseil-cpp
c++·abseil-cpp
星星也在雾里19 小时前
内网服务对外访问:cpolar 内网穿透完整教程
网络·tcp/ip
ComputerInBook20 小时前
C++ 17 相比 C++ 14 新增之特征
开发语言·c++·c++ 17
皮卡蛋炒饭.20 小时前
传输层协议TCP
服务器·网络·tcp/ip
Peter·Pan爱编程20 小时前
引用:比指针更安全的别名
c++·指针·引用·c++基础
m0_5027249520 小时前
golang 、java、c++、javascript 语言switch case异同
java·javascript·c++·golang
我命由我1234520 小时前
Android Framework P1 - 低配学习 Framework 方案、开机启动 Init 进程
android·c语言·c++·学习·android jetpack·android-studio·android runtime
许长安20 小时前
互斥锁、自旋锁、读写锁使用场景以及底层实现
c++·经验分享·笔记
Season45021 小时前
C++11并发支持库(condition_variable | future全家桶)
java·jvm·c++