前面写的程序都是 "自己跟自己玩"。真实的应用要联网—— 浏览器请求网页、聊天软件收发消息、爬虫抓数据。这篇老哥带你打通网络编程。
一、网络编程三要素
进程之间要通信,靠三个东西:
- 协议:定义通信规则(数据格式、传输顺序、错误检查);
- IP:网络中每台计算机的唯一标识,靠它找到计算机;
- 端口:标识进程的逻辑地址,靠它找到计算机里指定的进程。
二、TCP/IP 协议与分层模型
TCP/IP是互联网最常用的协议族,得名于两个核心协议:TCP(传输控制协议)和IP(网际协议)。
理解网络用五层模型(TCP/IP 四层 + 把网络接口层拆成数据链路层和物理层):
应用层 (HTTP、FTP、SMTP 等) 传输层 (TCP、UDP) 网络层 (IP) 数据链路层 物理层三、IP:标识设备、寻址
用ipconfig(Windows)/ifconfig(Linux)查看本机 IP。
公网 IP任何地方能访问;私网 IP只能在局域网内访问,范围:
10.0.0.0 ~ 10.255.255.255172.16.0.0 ~ 172.31.255.255192.168.0.0 ~ 192.168.255.255
127.0.0.1是回环地址,代表本机。
IPv432 位(如192.168.10.2),IPv6128 位(如2001:db8:0:1234:0:567:8:1)。IPv4 地址 2011 年已耗尽,IPv6 地址多到 "每粒沙子都能有 IP"。
四、端口:找到进程
端口号范围0~65535:
- 公认端口0~1023:绑定系统服务(80=HTTP、21=FTP、22=SSH、3306=MySQL、3389=RDP);
- 动态端口1024~65535:进程动态申请,关闭即释放。
用netstat -ano查看端口信息。
五、socket:进程通信的工具
socket(套接字)是进程间通信的工具。Python 用socket模块创建:
import socket # TCP 流式套接字 tcp_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) # UDP 数据报套接字 udp_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)AF_INET:用于 Internet 进程间通信;SOCK_STREAM:TCP 流式;SOCK_DGRAM:UDP 数据报。
六、UDP:不可靠但快
UDP简单、面向数据报、不保证可靠,发出去就不留备份。适合对时效要求高、能容忍丢包的场景(流媒体、在线游戏)。
UDP 服务端:
import socket udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_socket.bind(("127.0.0.1", 8080)) # 绑定 IP 和端口 while True: recv_data, client_addr = udp_socket.recvfrom(1024) # 接收 print(f"{client_addr[0]}:{client_addr[1]}>> {recv_data.decode('utf-8')}") udp_socket.sendto("你好".encode("utf-8"), client_addr) # 发送 udp_socket.close()UDP 客户端:
import socket udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while True: try: server_ip, server_port = "127.0.0.1", 8080 udp_socket.sendto(input(f"{server_ip}:{server_port}<< ").encode("utf-8"), (server_ip, server_port)) recv_data, client_addr = udp_socket.recvfrom(1024) print(f"{client_addr[0]}:{client_addr[1]}>> {recv_data.decode('utf-8')}") except KeyboardInterrupt: break udp_socket.close()先跑服务端再跑客户端,就能聊天了。
七、TCP:可靠但需连接
TCP面向连接、可靠、基于字节流,分建立连接→数据传送→终止连接三阶段,用序号、校验和、确认重传等机制保证可靠。适合网页、文件传输等不能丢数据的场景。
TCP 服务端(多了listen和accept):
import socket tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_socket.bind(("127.0.0.1", 8080)) tcp_socket.listen(2) # 设置监听 client_socket, client_addr = tcp_socket.accept() # 等待连接 while True: recv_data = client_socket.recv(1024) print(f"{client_addr[0]}:{client_addr[1]}>> {recv_data.decode('utf-8')}") client_socket.send("你好".encode("utf-8")) tcp_socket.close()TCP 客户端(多了connect):
import socket tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_socket.connect(("127.0.0.1", 8080)) # 连接服务器 while True: try: tcp_socket.send(input("127.0.0.1:8080<< ").encode("utf-8")) recv_data = tcp_socket.recv(1024) print(f"127.0.0.1:8080>> {recv_data.decode('utf-8')}") except KeyboardInterrupt: break tcp_socket.close()八、HTTP:网页的通信语言
HTTP(超文本传输协议)是应用层协议,万维网数据通信的基础。客户端发请求,服务器返回响应。
请求消息四部分:请求行(方法 + URI + 版本)、请求头、空行、请求体。
响应消息四部分:状态行(版本 + 状态码 + 状态信息)、响应头、空行、响应体。
八种请求方法:GET(读资源)、HEAD(只要元信息)、POST(提交数据)、PUT(上传内容)、DELETE(删除资源)、TRACE、OPTIONS、CONNECT。
五类状态码:
- 1xx信息:100 继续、101 切换协议;
- 2xx成功:200 OK、202 已接受;
- 3xx重定向:301 永久移动、302 临时移动、304 未修改;
- 4xx客户端错误:400 语法错误、403 拒绝、404 找不到、405 方法被禁止;
- 5xx服务器错误:500 内部错误、502 网关错误。
发 HTTP 请求拿数据(用 requests 库):
import requests url = 'https://international.v1.hitokoto.cn/' params = {'c': 'a', 'encode': 'json'} # 一言网的 API try: response = requests.get(url, params=params) status_code = response.status_code if status_code == 200: data = response.json() hitokoto = data['hitokoto'] from_who = data['from_who'] if data['from_who'] else '未知' print(f"随机名言: {hitokoto} - {from_who}") elif status_code == 404: print("请求的资源未找到!") elif status_code == 500: print("服务器内部错误!") else: print(f"发生未知错误,状态码: {status_code}") except requests.RequestException as e: print(f"请求过程中出现错误: {e}")老哥收尾
网络编程一句话:
三要素协议 / IP / 端口;TCP 可靠要连接、UDP 快但不稳;socket 建套接字,服务端 bind+listen+accept、客户端 connect;HTTP 请求响应、8 种方法、5 类状态码。
下一篇讲正则表达式—— 从文本里精准 "抠" 出想要的内容。有问题随时回来找老哥。