一、网络基础与Socket概念

各位同学,咱们今天正式开讲Socket编程。说实话,很多初学者一上来就撸代码,结果连数据怎么从A机器跑到B机器都没搞明白。我个人习惯是——先把底层的网络模型摸清楚,再动手写代码。这样你遇到问题的时候,脑子里有个地图,不会瞎猜。

1.1 TCP/IP协议栈:数据是怎么“跑”起来的?

你打开浏览器访问一个网站,数据从你的电脑出发,经过路由器、交换机,最后到达服务器。这中间经历了什么?

TCP/IP协议栈就是答案。它把网络通信分成了四层,每一层各司其职。我画了一张图,你看完就明白了。

TCP/IP 四层协议栈模型 应用层 HTTP · FTP · SMTP · DNS · WebSocket 传输层 TCP(可靠) · UDP(快速) 网络层 IP(寻址与路由) · ICMP · ARP 网络接口层 以太网 · WiFi · 物理介质 数据 段 包 帧

数据从应用层往下走,每一层都会加上自己的头部信息。到了接收端,再从下往上逐层拆包。这个过程叫“封装”和“解封装”。

各层核心职责:

层级 核心职责 常见协议/技术
应用层 为用户提供网络服务接口 HTTP、FTP、SMTP、DNS
传输层 端到端通信,数据分段与重组 TCP、UDP
网络层 寻址与路由选择 IP、ICMP、ARP
网络接口层 物理介质上的数据帧传输 以太网、WiFi

💡 我的经验:调试网络问题时,先确定问题出在哪一层。比如连不上服务器,先ping一下(网络层),通了再看端口(传输层)。一层一层排查,效率最高。

1.2 端口与IP地址:网络世界的“门牌号”

IP地址就像你家的门牌号,端口号就像你家的大门。数据包到了你家楼下(IP),还得知道从哪个门进去(端口)。

IP地址分类:

  • IPv4:32位,4个0-255的数字,比如 192.168.1.1。目前还是主流。
  • IPv6:128位,为了解决IPv4地址枯竭而生,比如 2001:db8::1。

端口号范围:

范围 分类 示例
0 - 1023 知名端口(Well-Known) HTTP:80, HTTPS:443, SSH:22
1024 - 49151 注册端口 MySQL:3306, Redis:6379
49152 - 65535 动态/私有端口 客户端临时分配

⚠️ 避坑指南:我曾经在项目里把服务端口设成了80,结果和系统自带的HTTP服务冲突,服务死活起不来。后来我养成了习惯——自定义服务一律用1024以上的端口,并且先在服务器上 netstat -tlnp 查一下端口占用情况。

1.3 Socket是什么?

Socket,中文叫“套接字”。说白了,它就是操作系统提供的一个编程接口,让应用程序能通过网络发送和接收数据。

你想想看,如果没有Socket,你要自己处理TCP/IP协议栈的每一层细节——自己组装IP包、自己处理重传、自己管理连接状态。那得写到猴年马月去?

Socket把这一切都封装好了。你只需要:

  1. 创建一个Socket
  2. 绑定地址和端口
  3. 监听或连接
  4. 收发数据
  5. 关闭Socket

就这么简单。内核帮你搞定了底层所有脏活累活。

核心理解:Socket是应用层与传输层之间的桥梁。你写的代码在应用层,通过Socket调用内核的传输层能力。没有Socket,网络编程就是一场噩梦。

1.4 Socket类型:TCP vs UDP

Socket分两种主流类型,对应传输层的两个协议。我直接给你对比清楚:

特性 TCP Socket UDP Socket
连接方式 面向连接(先握手,再通信) 无连接(直接发数据)
可靠性 可靠传输,有重传机制 不可靠,丢了不重发
数据顺序 保证数据按序到达 不保证顺序
传输效率 相对较低(有开销) 高(无握手、无确认)
典型应用 HTTP网页、文件传输、邮件 视频直播、DNS查询、游戏
Socket类型 SOCK_STREAM SOCK_DGRAM

怎么选?我个人的经验是:

  • 如果你的数据不能丢(比如银行转账、文件下载),用TCP。
  • 如果你追求速度,能容忍偶尔丢包(比如视频通话、在线游戏),用UDP。

💡 一个小故事:我以前做过一个实时对战游戏,一开始用的TCP。结果玩家一多,延迟高得离谱。后来换成UDP,自己实现了一个轻量级的可靠传输层,延迟降了60%。选对协议,事半功倍。

1.5 Socket工作流程:一张图说清楚

TCP Socket的通信流程是固定的。我画了张流程图,你跟着走一遍就懂了。

TCP Socket 通信流程 服务器 客户端 socket() 创建套接字 bind() 绑定地址和端口 listen() 监听连接 accept() 接受连接 recv() / send() 收发数据 close() 关闭连接 socket() 创建套接字 connect() 连接服务器 send() / recv() 收发数据 close() 关闭连接 三次握手 数据流

流程其实就八个字:创建、绑定、监听、连接、收发、关闭。服务器和客户端是对称的,但角色不同。服务器是被动方,等着客户端来连;客户端是主动方,发起连接请求。

记住这个流程:后面每一章的代码,都是在这个框架上做文章。单线程、多线程、IO多路复用、异步——万变不离其宗。

1.6 本章小结

这一章我们聊了:

  • TCP/IP协议栈的四层结构,以及每层的职责
  • IP地址和端口号,它们是网络通信的“门牌号”
  • Socket的本质——操作系统提供的网络编程接口
  • TCP Socket和UDP Socket的区别与选型
  • Socket通信的标准流程