文章目录
1. TCP/IP协议
1.1 IP协议
1.2 TCP协议
2. UDP协议
3. Socket
4. TCP编程
4.1 创建TCP服务器
4.2 创建TCP客户端
4.3 简易聊天工具
5. UDP编程
5.1 创建UDP服务器
5.2 创建UDP客户端
learning from 《python web开发从入门到精通》
1. TCP/IP协议
大家都用同样的协议 protocol(沟通语言)才能对话
TCP/IP协议:
应用层:FTP文件传输,Telnet远程登录,DNS域名系统,SMTP电子邮件传输…(为用户提供服务)
传输层:TCP传输控制,UDP用户数据报(端到端通信,保证顺序传输数据和完整性)
网络层:IP网际协议,IGMP互联网组管理,ICMP互联网控制报文(主机到主机通信)
链路层:(监视数据在主机和网络之间的交换)
1.1 IP协议
数据被分成小包裹通过 IP包发出,不保证到达,不保证顺序
1.2 TCP协议
建立在 IP 协议之上,3次握手,建立可靠连接,保证数据顺序到达
丢失,自动重发
TCP 报文 包含数据,源IP,目标IP,源端口,目标端口
2. UDP协议
面向无连接的协议,不需建立连接,只需知道对方 IP 和端口
不保证一定到达,但是速度比 TCP 快
3. Socket
两个程序要网络通信,都需要使用 Socket 套接字(孔,插座的意思)
用于描述 IP 地址 和 端口
服务打开一个 Socket,并绑定到一个端口上,不同的端口对应不同的服务
python中的套接字:
s = socket.socket(AddressFamily, Type)
AddressFamily,填socket.AF_INET (用于 Internet 进程间通信),填socket.AF_UNIX(用于同一台机器进程间通信)
Type 套接字类型,socket.SOCK_STREAM 流式套接字(主要用于 TCP),socket.SOCK_DGRAM 数据包套接字(主要用于 UDP)
4. TCP编程
主动发起连接的是:客户端
被动响应连接的是:服务器
4.1 创建TCP服务器
1.创建套接字
2.bind 绑定 IP 和 端口
3.listen socket 可以被动连接
4.accept 等待客户端连接
5.recv / send 接收发送数据
例子:使用 socket 模块,通过客户端浏览器 向 本地服务器(127.0.0.1) 发起请求;服务器接到请求,向浏览器发送 hello world
import socket host = "127.0.0.1" # IP port = 8080 # 端口 web = socket.socket(socket.AF_INET, socket.SOCK_STREAM) web.bind((host, port)) # 绑定端口 web.listen(5) # 监听,最多5个连接 print("服务器启动成功, 等待客户端连接...") while True: conn, addr = web.accept() # 建立客户端连接 print("客户端连接成功, 地址:", addr) data = conn.recv(1024) # 获取客户端发送的数据 print("接收到客户端发送的数据:", data.decode()) conn.sendall(b'HTTP/1.1 200 OK\r\n\r\nHello World, Michael!') # 发送数据给客户端 conn.close() # 关闭连接 print("客户端连接关闭")
服务器启动成功, 等待客户端连接... 客户端连接成功, 地址: ('127.0.0.1', 7631) 接收到客户端发送的数据: GET / HTTP/1.1 Host: 127.0.0.1:8080 Connection: keep-alive sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Microsoft Edge";v="96" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.34 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: none Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 客户端连接关闭 客户端连接成功, 地址: ('127.0.0.1', 7632) 接收到客户端发送的数据: GET /favicon.ico HTTP/1.1 Host: 127.0.0.1:8080 Connection: keep-alive sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Microsoft Edge";v="96" sec-ch-ua-mobile: ?0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.34 sec-ch-ua-platform: "Windows" Accept: image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: no-cors Sec-Fetch-Dest: image Referer: http://127.0.0.1:8080/ Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 客户端连接关闭
4.2 创建TCP客户端
客户端比较简单一点
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = "127.0.0.1" port = 8080 s.connect((host, port)) while True: send_data = input("请输入要发送的数据:") if send_data == "exit": break s.send(send_data.encode("utf-8")) recvData = s.recv(1024).decode("utf-8") # 最大接收1024字节 print("接收到的数据:", recvData) s.close()
4.3 简易聊天工具
服务端
import socket host = socket.gethostname() port = 12345 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host, port)) s.listen(1) sock, addr = s.accept() print('建立连接:', addr) info = sock.recv(1024).decode() while info != "byebye": if info: print("收到信息:", info) send_data = input("请输入发送的信息:") sock.send(send_data.encode()) if send_data == "byebye": break info = sock.recv(1024).decode() sock.close() s.close()
客户端
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() port = 12345 s.connect((host, port)) print("已经连接到服务器") info = '' while info != 'byebye': send_data = input("请输入要发送的数据:") s.send(send_data.encode()) if send_data == 'byebye': break info = s.recv(1024).decode() print("收到服务器的数据:", info) s.close()
5. UDP编程
UDP 面向消息的协议,无需建立连接,传输是不可靠的,一般用于:
语音广播,视频,聊天软件,TFTP(简单文件传送),SNMP(简单网络管理协议),RIP(路由信息协议),DNS(域名解释)
5.1 创建UDP服务器
例子:在客户端输入摄氏温度,发送给服务器,转换为华氏温度,发送给客户端显示
import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP套接字 s.bind(('127.0.0.1', 1314)) print('绑定 UDP服务 到 1314 端口') data, addr = s.recvfrom(1024) # 收到的数据是 byte 类型 data = float(data) * 1.8 + 32 send_data = "转换后的温度(华氏温度):" + str(data) print("从%s:%s收到请求数据" % addr) s.sendto(send_data.encode('utf-8'), addr) # 发送数据给客户端 s.close()
5.2 创建UDP客户端
import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) data = input("请输入要转换的摄氏温度:") s.sendto(data.encode(), ("127.0.0.1", 1314)) print(s.recv(1024).decode()) s.close()