首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux网络:socket网络套接字

Linux网络:socket网络套接字

原创
作者头像
技术文章分析
发布2025-09-21 14:00:37
发布2025-09-21 14:00:37
1100
代码可运行
举报
文章被收录于专栏:技术技术
运行总次数:0
代码可运行

Socket(套接字)是网络编程的基石,它为不同主机上的进程间通信(IPC)提供了一个统一的编程接口。在 Linux 系统中,Socket 编程遵循 BSD Socket API,这套接口非常强大且被广泛支持。


1. 什么是 Socket?

可以将 Socket 想象成一个端点(Endpoint),它代表了网络通信的一端。就像电话通信需要一个电话号码和一部电话机一样,网络通信也需要一个地址(IP + 端口)和一个用于收发数据的“接口”,这个接口就是 Socket。

  • 核心作用:Socket 是应用层与传输层之间的一个抽象层,它把复杂的 TCP/IP 协议族隐藏在背后,为应用程序提供了一套简单的接口(如 send, recv, connect, listen 等)。
  • 文件描述符:在 Linux 中,Socket 也被视为一种特殊的文件。创建一个 Socket 会返回一个文件描述符(File Descriptor),后续的读写操作(read, write 或专用的 send, recv)都通过这个文件描述符进行,这体现了 Linux “一切皆文件”的哲学。

2. Socket 的关键属性

一个 Socket 由以下几个关键属性定义:

  • 协议族(Protocol Family / Domain):
    • AF_INET: IPv4 协议族。
    • AF_INET6: IPv6 协议族。
    • AF_UNIX / AF_LOCAL: 本地进程间通信(Unix Domain Socket)。
    • 最常用的是 AF_INET
  • Socket 类型(Socket Type):
    • SOCK_STREAM: 面向连接的、可靠的、基于字节流的服务。通常使用 TCP 协议。数据按顺序到达,无重复。
    • SOCK_DGRAM: 无连接的、不可靠的、基于数据报的服务。通常使用 UDP 协议。数据以独立的数据包发送,可能丢失、重复或乱序。
    • SOCK_RAW: 原始套接字,允许直接访问底层网络协议(如 IP、ICMP),用于开发网络工具(如 ping, traceroute)。
  • 协议(Protocol):
    • 通常设置为 0,表示使用默认协议(SOCK_STREAM 对应 TCP,SOCK_DGRAM 对应 UDP)。
    • 可以明确指定,如 IPPROTO_TCP, IPPROTO_UDP

3. 基于 TCP 的 Socket 编程流程(面向连接)

这是最常见和最可靠的通信模式。

3.1 服务器端(Server)
  1. 创建 Socket (socket): c深色版本int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建一个用于监听的套接字
    • 返回一个文件描述符 sockfd
  2. 绑定地址和端口 (bind): c深色版本struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡 server_addr.sin_port = htons(PORT); // 绑定端口号 bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    • 将服务器的 IP 地址和端口号与创建的 Socket 关联起来。
  3. 监听连接 (listen): c深色版本listen(sockfd, BACKLOG);
    • 将 Socket 状态从 CLOSED 变为 LISTEN,开始等待客户端的连接请求。
    • BACKLOG 参数指定了等待连接队列的最大长度。
  4. 接受连接 (accept): c深色版本struct sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); int client_fd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);
    • 阻塞等待客户端连接。
    • 成功后,返回一个新的文件描述符 client_fd,专门用于与这个特定的客户端通信。
    • 原来的 sockfd 继续用于监听新的连接。
  5. 数据通信 (read/writerecv/send): c深色版本char buffer[1024]; int n = read(client_fd, buffer, sizeof(buffer)); // 从客户端读取数据 write(client_fd, "Hello Client!", 13); // 向客户端发送数据
  6. 关闭连接 (close): c深色版本close(client_fd); // 关闭与特定客户端的连接 close(sockfd); // 关闭监听套接字(程序结束时)
3.2 客户端(Client)
  1. 创建 Socket (socket): c深色版本int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  2. 连接服务器 (connect): c深色版本struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("服务器IP"); server_addr.sin_port = htons(PORT); connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    • 向服务器发起连接请求。成功后,TCP 三次握手完成。
  3. 数据通信 (read/write): c深色版本write(sockfd, "Hello Server!", 13); // 发送数据到服务器 char buffer[1024]; int n = read(sockfd, buffer, sizeof(buffer)); // 从服务器接收数据
  4. 关闭连接 (close): c深色版本close(sockfd);

4. 基于 UDP 的 Socket 编程流程(无连接)

UDP 是无连接的,因此流程更简单,但需要自己处理可靠性。

4.1 服务器端(Server)
  1. 创建 Socket: c深色版本int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  2. 绑定地址和端口 (bind): c深色版本bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
代码语言:javascript
代码运行次数:0
运行
复制
ONLINE.SDDANTUOJI.CN24丨JRS.XLSY.CN80丨MAP.HZBESTSEO.COM32丨ZHIBO.JS-SJL.CN68
WEIBO.SDDANTUOJI.CN88丨WEIBO.CSWDYS.COM68丨VIP.JXLGDL.COM16丨M.ZYZJZD.CN72
ZHIBO8.ZYZJZD.CN92丨CCTV.ZYZJZD.CN63丨VIP.NMFZTD.ORG.CN87丨FOOTBALL.PORTASTYL.COM52
FREE.ZYZJZD.CN62丨WEIBO.HZBESTSEO.COM90丨24K.SDDANTUOJI.CN95丨SINA.NMFZTD.ORG.CN81
XLSY.CN88丨24K.CZCJJC.CN93丨24K.HZBESTSEO.COM34丨ZHIBO8.NMFZTD.ORG.CN91
FOOTBALL.JS-SJL.CN80丨ZUQIU.NMFZTD.ORG.CN68丨ZB.SDDANTUOJI.CN18丨ZUQIU.JS-SJL.CN49
PRETTY.HZBESTSEO.COM70丨MOBI.PORTASTYL.COM93丨ZHIBO.JXLGDL.COM44丨SHARE.JXLGDL.COM82
VIP.XLSY.CN93丨QQ.NMFZTD.ORG.CN53丨SHARE.XLSY.CN80丨MOBI.CSWDYS.COM49
LIVE.PORTASTYL.COM86丨ZUQIU.XLSY.CN42丨JRS.CZCJJC.CN54丨BOLL.SDDANTUOJI.CN93
ONLINE.ZYZJZD.CN41丨WWW.JS-SJL.CN54丨BOLL.CZCJJC.CN38丨JRS.JXLGDL.COM43
M.HZBESTSEO.COM46丨TV.PORTASTYL.COM16丨ZB.JXLGDL.COM22丨24K.CSWDYS.COM53
  1. 接收数据 (recvfrom): c深色版本struct sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); char buffer[1024]; int n = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&client_addr, &client_len);
    • recvfrom 会返回发送方的地址信息(IP 和端口),这对于后续回复至关重要。
  2. 发送数据 (sendto): c深色版本sendto(sockfd, "Hello UDP Client!", 17, 0, (struct sockaddr*)&client_addr, client_len);
    • 使用 sendto 指定目标地址。
  3. 关闭 (close): c深色版本close(sockfd);
4.2 客户端(Client)
  1. 创建 Socket: c深色版本int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  2. 发送数据 (sendto): c深色版本sendto(sockfd, "Hello UDP Server!", 17, 0, (struct sockaddr*)&server_addr, sizeof(server_addr));
    • 客户端通常不需要 bind,系统会自动分配一个临时端口。
  3. 接收数据 (recvfrom): c深色版本char buffer[1024]; int n = recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL); // 通常不关心服务器的地址,或者已经知道
  4. 关闭 (close): c深色版本close(sockfd);

5. 重要概念与注意事项

  • 字节序(Byte Order):
    • 网络传输使用大端序(Big-Endian)
    • 主机字节序可能是小端序或大端序。
    • 使用 htons() (host to network short), htonl() (host to network long), ntohs(), ntohl() 进行转换,特别是端口号和 IP 地址。
  • IP 地址转换:
    • inet_addr(): 将点分十进制字符串(如 "192.168.1.1")转换为网络字节序的整数。
    • inet_ntoa(): 反向转换。
    • 更现代的函数:inet_pton()inet_ntop(),支持 IPv4 和 IPv6。
  • 阻塞与非阻塞 I/O:
    • 默认情况下,Socket 是阻塞的(如 accept, read 会等待)。
    • 可以通过 fcntl() 设置为非阻塞模式,配合 select, poll, epoll 实现高并发(I/O 多路复用)。
  • 错误处理:
    • 几乎每个 Socket 系统调用都可能失败,必须检查返回值(通常为 -1 表示错误),并使用 perror()strerror(errno) 打印错误信息。
  • 优雅关闭:
    • 使用 shutdown() 可以单独关闭读或写方向。
    • close() 会释放文件描述符并尝试关闭连接。

6. 总结

Socket 是 Linux 网络编程的核心。理解其工作原理和编程流程是开发网络应用的基础。

  • TCP:可靠、有序、面向连接,适用于 HTTP、FTP、SSH 等。
  • UDP:快速、轻量、无连接,适用于 DNS、视频流、实时游戏等对速度要求高、能容忍少量丢包的场景。

掌握 Socket 编程,你就能构建从简单的客户端/服务器应用到复杂的网络服务。建议从编写一个简单的 TCP 回显服务器/客户端开始实践。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是 Socket?
  • 2. Socket 的关键属性
  • 3. 基于 TCP 的 Socket 编程流程(面向连接)
    • 3.1 服务器端(Server)
    • 3.2 客户端(Client)
  • 4. 基于 UDP 的 Socket 编程流程(无连接)
    • 4.1 服务器端(Server)
    • 4.2 客户端(Client)
  • 5. 重要概念与注意事项
  • 6. 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档