计算机⽹络及TCP⽹络应⽤程序开发

一、 网络基础概念

1.网络的定义与目的

  • 定义 :将具有独立功能的多台计算机通过通信设备与线路连接起来,在网络软件和协议的管理协调下,实现资源共享信息传递的系统。

  • 目的 :进行网络编程,开发基于网络通信的应用程序。

2. IP地址 (Internet Protocol Address)

作用:网络设备的唯一逻辑标识,用于定位和寻址。

分类

IPv4 :32位地址,点分十进制表示(如 192.168.1.1),地址池近乎枯竭。

IPv6 :128位地址,十六进制表示(如 2001:0db8::1),解决IPv4地址不足问题。

查看命令 :Linux/macOS: ifconfig,Windows: ipconfig

连通性测试ping <IP或域名>

3. 端口 (Port) 与端口号 (Port Number)

端口:设备与外界通信交流的出口,是数据传输的通道。

端口号:用于标识端口的整数(0-65535)。

为什么需要端口 :IP地址只能定位到设备,端口号才能指定设备上具体的应用程序(进程)。

分类

知名端口 (Well-known Ports):0-1023,分配给系统核心服务(如HTTP:80, HTTPS:443, SSH:22, FTP:21)。

动态端口 (Dynamic Ports):1024-65535,供普通应用程序使用。

4. URL (统一资源定位符)

作用:完整描述互联网上资源地址的字符串。

标准格式<协议>://<主机名>:<端口号>/<路径>?<查询参数>#<片段锚点>

示例解析https://www.example.com:8080/api/users?id=1001#profile

协议(Scheme): https

主机名(Host): www.example.com

端口(Port): 8080 (HTTPS默认443,可省略)

路径(Path): /api/users

查询字符串(Query): ?id=1001

片段(Fragment): #profile (客户端使用,不发送到服务器)

概念 说明
IP地址 网 络中设备的唯一逻辑地址,用于标识和定位设备。
IPv4 32位地址,点分十进制表示(如 192.168.1.1),约42亿个地址。
IPv6 128位地址,十六进制表示(如 2001:0db8::1),解决IPv4地址耗尽问题。
URL (统一资源定位符) 用于定位互联网上资源的地址。完整格式:协议://域名:端口/路径?查询参数#锚点

二、同源与跨域 (Same-Origin vs. Cross-Origin)

特性 同源 (Same-Origin) 跨域 (Cross-Origin)
定义 协议、域名、端口完全相同 协议、域名、端口有任一不同
示例 https://example.com/apphttps://example.com/api https://example.comhttp://example.com (协议不同)
访问权限 完全访问 DOM、Cookie、AJAX 请求 默认禁止 访问,受同源策略限制
解决方案 无需特殊处理 CORS (跨域资源共享)、JSONP、代理服务器、WebSocket

同源策略 (SOP):浏览器的核心安全机制,防止恶意网站窃取另一个网站的数据。

三、Socket 套接字及使用场景

方面 说明
是什么 网络通信的端点(Endpoint),是应用程序通过网络协议进行数据交互的接口
比喻 IP地址是地址,端口是门牌号,Socket就是连接两扇门的电话线
使用场景 任何网络通信!包括Web服务(HTTP/HTTPS)、邮件(SMTP/POP3)、文件传输(FTP)、数据库连接、实时通信(游戏、聊天)等。
本质 封装了底层网络协议(如TCP/IP)的复杂操作,为程序员提供简单的API(如 send(), recv(), connect())。

四、TCP 与 UDP 的特点与区别

特性 TCP (传输控制协议) UDP (用户数据报协议)
连接性 面向连接 (需三次握手) 无连接 (直接发送)
可靠性 可靠传输 (确认、重传、校验) 不可靠传输 (可能丢失、乱序)
数据顺序 保证数据顺序 不保证数据顺序
速度/开销 速度慢,开销大(有控制机制) 速度快,开销小 (无控制机制)
流量控制 有 (滑动窗口)
应用场景 网页浏览(HTTP/S)、邮件(SMTP)、文件传输(FTP)、远程登录(SSH) 视频流、语音通话(VoIP)、在线游戏、DNS查询、直播
比喻 打电话:需要接通,确认对方听到,有条理地对话。 对讲机/发传单:直接说,不管对方是否收到,可能听不清。

五、TCP的可靠传输机制与连接管理

1 可靠传输机制

确认应答 (ACK):接收方收到数据后必须回复确认消息。

超时重传 (Retransmission):发送方在一定时间内未收到ACK,会重发数据。

序列号与确认号:为每个字节编号,解决乱序和重复问题。

流量控制 (Flow Control):通过滑动窗口机制,防止发送过快导致接收方缓冲区溢出。

拥塞控制 (Congestion Control):通过慢启动、拥塞避免等算法,避免网络过载。

2 TCP 三次握手与四次挥手

三次握手 (建立连接 - 我要和你打电话)

  1. SYN :客户端 -> 服务器。"你好,我能和你连接吗?" (SYN_SENT)

  2. SYN-ACK :服务器 -> 客户端。"收到,我可以连接,你准备好了吗?" (SYN_RCVD)

  3. ACK :客户端 -> 服务器。"好的,我准备好了,开始通信吧!" (ESTABLISHED)

" TCP三次握⼿" 是指在计算机⽹络中,TCP协议(传输控制协议)建⽴连接时所进⾏的⼀种过程。具 体来说,它包含以下三个步骤:

  1. 第⼀次握⼿:客户端发送⼀个带有SYN(同步序列编号)标志的TCP报⽂到服务器,表示请求建 ⽴连接。此时客户端进⼊SYN-SENT(同步已发送)状态。

  2. 第⼆次握⼿:服务器收到客户端的SYN报⽂后,会回复⼀个带有SYN和ACK(确认)标志的TCP 报⽂给客户端,其中ACK是对客户端SYN报⽂的确认,同时服务器⾃⼰也发送⼀个SYN报⽂,表 示⾃⼰也想建⽴连接。此时服务器进⼊SYN-RCVD(同步已接收)状态。

  3. 第三次握⼿:客户端收到服务器的SYN+ACK报⽂后,再发送⼀个带有ACK标志的TCP报⽂给服 务器,对服务器的SYN报⽂进⾏确认。此时客户端进⼊ESTABLISHED(已建⽴连接)状态,服 务器收到客户端的ACK报⽂后,也进⼊ESTABLISHED状态,⾄此TCP连接建⽴完成。

这种三次握⼿的过程可以有效防⽌出现错误的连接建⽴,确保双⽅都准备好进⾏数据传输。

四次挥手 (断开连接 - 我要挂电话了)

  1. FIN :客户端 -> 服务器。"我说完了,要挂电话了。" (FIN_WAIT_1)

  2. ACK :服务器 -> 客户端。"等等,我还没说完..." (CLOSE_WAIT / FIN_WAIT_2)

  3. FIN :服务器 -> 客户端。"好了,我也说完了,可以挂了。" (LAST_ACK)

  4. ACK :客户端 -> 服务器。"好的,再见!" (TIME_WAIT -> 等待后 CLOSED)

" TCP四次挥⼿" 是指TCP协议在断开连接时所进⾏的四次交互过程。具体如下:

  1. 第⼀次挥⼿:主机A(客户端)向主机B(服务器)发送⼀个FIN(Finish)报⽂,表示A想要关闭 连接,进⼊" FIN_WAIT_1" 状态。这个FIN报⽂的序号是seq = u,u是⼀个随机的序号值。

  2. 第⼆次挥⼿:主机B收到A的FIN报⽂后,会发送⼀个ACK(Acknowledgment)报⽂给A,表示B 已经收到A的关闭连接请求。这个ACK报⽂的序号是seq = v,确认号是ack = u + 1,表示B确认 了A的FIN报⽂。此时,B进⼊" CLOSE_WAIT" 状态,⽽A进⼊" FIN_WAIT_2" 状态。

  3. 第三次挥⼿:主机B在处理完⾃⼰的事务后,也会向主机A发送⼀个FIN报⽂,表示B也想要关闭 连接。这个FIN报⽂的序号是seq = w,确认号是ack = u + 1。此时,B进⼊" LAST_ACK" 状态。

  4. 第四次挥⼿:主机A收到B的FIN报⽂后,会发送⼀个ACK报⽂给B,表示A已经收到B的关闭连接 请求。这个ACK报⽂的序号是seq = u + 1,确认号是ack = w + 1。此时,A进 ⼊" TIME_WAIT" 状态,等待2MSL(Maximum Segment Lifetime)时间后,如果没有收到B的 任何报⽂,A就正式关闭连接,进⼊" CLOSED" 状态。⽽B在收到A的ACK报⽂后,也进 ⼊" CLOSED" 状态,完成整个断开连接的过程。

TCP四次挥⼿的⽬的是确保双⽅在断开连接时能够安全、可靠地完成数据传输,并且双⽅都能明确知 道对⽅已经关闭了连接

为什么挥手多一次?

因为TCP连接是全双工的,每一方向必须单独关闭。

六、TCP 网络应用程序开发总结

1 TCP 发送数据基本流程 (客户端)

代码:

python 复制代码
graph TD
    A[创建Socket对象] --> B[建立连接 connect]
    B --> C[发送数据 send]
    C --> D[关闭连接 close]

2 TCP 接收数据基本流程 (服务端)

代码:

python 复制代码
graph TD
    A[创建Socket对象] --> B[绑定IP和端口 bind]
    B --> C[设置监听 listen]
    C --> D[等待连接 accept<br>阻塞直到客户端连接]
    D -- 连接成功, 返回新Socket --> E[接收数据 recv]
    E --> F[发送响应 send]
    F --> G[关闭客户端连接 close]
    G --> D

3 核心开发流程

步骤 客户端 (Client) 服务器端 (Server)
1. 创建Socket socket.socket() socket.socket()
2. 绑定地址 (通常系统自动分配) 必须 .bind((host, port))
3. 建立连接 主动 .connect((server_ip, server_port)) 被动 .listen(backlog)
4. 接受连接 - .accept() -> 返回新Socket
5. 数据传输 .send() / .recv() 使用accept返回的新Socket 进行 .send() / .recv()
6. 关闭连接 .close() 先关新Socket,再关监听Socket

4 关键注意事项

  1. 字节流编码 :网络传输的是字节(bytes)。发送前需.encode('utf-8'),接收后需.decode('utf-8')

  2. 监听Socket vs 通信Socket

    • 监听Socket :仅用于接受新连接 (accept()),不能收发数据。

    • 通信Socketaccept() 返回的新Socket,用于与特定客户端进行数据通信。

  3. 多客户端并发 :默认的accept() -> recv() -> send()是串行的。处理多客户端必须使用 多线程多进程I/O多路复用 (如 selectors 模块)。

  4. 连接状态判断 :如果 recv() 返回空数据(长度为0的bytes),则表示对方已关闭连接。

  5. 端口复用:服务器重启时避免"Address already in use"错误。

python 复制代码
# 在bind()之前设置
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

示例:

编写一个TCP回声服务器和客户端程序:

· 服务器监听本地端口8888

· 客户端连接到服务器后,用户可以输入任意字符串

· 服务器将接收到的消息原样返回给客户端

· 客户端显示服务器返回的消息

· 当用户输入"quit"时,客户端和服务器都应正常关闭连接

要求:

· 服务器能够同时处理多个客户端连接(使用多线程或多进程)

· 客户端和服务器都需要有适当的错误处理

· 代码结构清晰,有必要的注释

服务端代码(server.py):

python 复制代码
import threading
import socket

# 关于对处理客户端的连接
def handle(new_socket, ip_port):
    print(f"新的连接:{ip_port}")

    try:
        while True:
            data = new_socket.recv(1024).decode('utf-8')
            # 判断是否收到空数据
            if not data:
                print(f"客户端 {ip_port} 断开连接")
                break
            # 打印收到的消息和客户端的信息
            print(f"收到来自 {ip_port} 的消息: {data}")
            #   检测是否有退出的请求
            if data == "quit":
                print(f"客户端 {ip_port} 请求退出连接")
                new_socket.send("服务器连接关闭".encode("utf-8"))
                break
            # 发送从客户端传过来的信息
            new_socket.send(data.encode('utf-8'))
    # 捕获异常
    except Exception as e:
        print(f"客户端 {ip_port}: 发生错误 {e}")
    finally:
        new_socket.close()
        print(f"与客户端 {ip_port} 的连接已断开")

#   启动tcp的服务端函数
def start_server(host='127.0.0.1', port=8080):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        server_socket.bind((host, port))
        # 开始接听连接
        server_socket.listen(5)
        print(f"服务器启动, 监听: {host}:{port}")
        print("等待客户端连接...")

        while True:
            new_socket, ip_port = server_socket.accept()
            client_thread = threading.Thread(target=handle, args=(new_socket, ip_port))
            client_thread.daemon = True
            client_thread.start()
            print(f"活跃线程数: {threading.active_count()-1}")
    #   捕获异常
    except Exception as e:
        print(f"服务器错误: {e}")
    finally:
        server_socket.close()
        print("服务器已关闭")


if __name__ == '__main__':
    start_server()

客户端代码(client.py):

python 复制代码
import socket

#   启动客户端的函数
def start_client(host='127.0.0.1', port=8080):
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        client_socket.connect((host, port))
        print(f'已连接到服务器 {host}:{port}')
        print("输入消息发送到服务器, 发送quit退出")

        while True:
            message = input("请输入: ")
            client_socket.send(message.encode('utf-8'))

            if message == 'quit':
                break

            data = client_socket.recv(1024).decode('utf-8')
            print(f"服务器的回复: {data}")
    except Exception as e:
        print(f"客户端错误: {e}")
    finally:
        client_socket.close()
        print("连接已关闭")


if __name__ == '__main__':
    start_client()

六、 总结

网络基础 :理解 IP地址 (定位设备)、端口 (定位应用)、Socket (通信工具) 是网络编程的基石。

协议选择 :根据应用场景在可靠但慢的TCP快速但不可靠的UDP之间做出权衡。

TCP精髓 :其可靠性 源于复杂的机制(握手、挥手、确认、重传、控制),其开发流程围绕"建立连接->传输->关闭连接"展开。

开发关键 :严格遵循开发流程,深刻理解字节编码双Socket分工多客户端并发处理,是写出稳定高效TCP程序的关键。

相关推荐
qq_386322699 小时前
华为网路设备学习-32(BGP协议 七)路由反射器与联邦
网络·学习
兰雪簪轩11 小时前
分布式通信平台测试报告
开发语言·网络·c++·网络协议·测试报告
fuyongliang12312 小时前
linux Nginx服务配置介绍,和配置流程
运维·服务器·网络
GEO_YScsn13 小时前
Rust 的生命周期与借用检查:安全性深度保障的基石
网络·算法
司徒小夜14 小时前
HTTP与HTTPS杂谈-HTTPS防御了什么
网络·http·https
只因在人海中多看了你一眼14 小时前
B.50.10.09-RPC核心原理与电商应用
qt·网络协议·rpc
嫩萝卜头儿15 小时前
虚拟地址空间:从概念到内存管理的底层逻辑
linux·服务器·网络
LJC_Superman16 小时前
Web与Nginx网站服务
运维·服务器·前端·网络·数据库·nginx·vim
小鸟啄米16 小时前
Elixir通过Onvif协议控制IP摄像机,扩展ExOnvif的摄像头停止移动 Stop 功能
网络协议·elixir·onvif