网络编程:TCP与UDP
相关概念
-
OSI七层模型:开放系统互连参考模型 (Open System Interconnect 简称OSI)是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型,为开放式互连信息系统提供了一种功能结构的框架。它从低到高分别是:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
-
TCP/IP:在OSI七层模型的基础上简化出来的一套网络协议族,共有4层,得到了广泛使用。
-
TCP:传输控制协议
- 有连接的,数据传输是可靠的(数据检查)
- 传输速度稍慢,三次握手、四次挥手
-
UDP:用户数据报协议
- 无连接的,数据传输是不可靠的
- 传输速度较快
-
IP地址:计算机的唯一标识
- windows查看IP:ipconfig
-
ping:查看网络连通性
- 示例:
ping 域名/IP
- 示例:
-
端口号:每个应用都有自己的端口号
- 范围:0~65535
- 公认端口:0~1023
http: 80 https: 443 smtp: 25 ftp: 21 ssh: 22
- 其他端口:1024~65535
-
网络编程核心
- IP + 端口号
- 库:
socket
TCP协议
-
说明:面向连接的、数据可靠、三次握手、四次挥手、传输速度稍慢
-
原理:见图片
-
示例:模拟http协议请求百度服务器的数据
import socket # 创建一个套接字 # family:协议族,socket.AF_INET表示IPV4 # type:传输协议,socket.SOCK_STREAM表示TCP skt = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) # 连接指定的服务器 skt.connect(('www.baidu.com', 80)) # 向服务器发送数据(模拟HTTP协议数据) skt.send(b'GET / HTTP/1.1\r\nHost:www.baidu.com\r\nConnection:close\r\n\r\n') # 接受服务器发来的数据 data = [] while True: temp = skt.recv(1024) if temp: data.append(temp) else: break # 关闭套接字 skt.close() # 拼接内容 content = b''.join(data).decode('utf-8') # 按照空行进行切割,得到头部和内容 headers, body = content.split('\r\n\r\n', 1) print(headers)
-
TCP协议的服务器与客户端
skt = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) # 绑定主机 skt.bind(('10.8.152.25', 8888)) # 监听服务 skt.listen() # 等待连接(会阻塞) client_skt, client_addr = skt.accept() while True: # 接收客户端数据 recv_data = client_skt.recv(1024) print('大花:', recv_data.decode('utf-8')) # 向客户端发送原样的数据 client_skt.send(recv_data) if recv_data == b'byebye': break client_skt.close() skt.close()
import socket skt = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) skt.connect(('10.8.152.52', 8888)) while True: data = input('>>>:') # 发送给服务器 skt.send(data.encode('utf-8')) # 接收来自服务器的数据 recv_data = skt.recv(1024) print('服务器:', recv_data.decode('utf-8')) if recv_data == b'byebye': break skt.close()
UDP协议
-
说明:面向无连接、数据不可靠、传输速度较快,适应于对数据要求不严格的情况
-
原理:见图片
-
示例:模拟飞秋数据
import socket # socket.SOCK_DGRAM表示UDP协议 skt = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) # 准备数据 '版本号:数据报序号:用户名:主机名:命令:消息内容[:附加数据]' data = '1:123456:zhangsan:windows:32:hello!' ip = '192.168.72.1' port = 2425 skt.sendto(data.encode('gbk'), (ip, port))
-
UDP协议的服务器与客户端
import socket skt = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) skt.bind(('10.8.152.52', 9999)) while True: recv_data, client_addr = skt.recvfrom(1024) print(client_addr, recv_data.decode('utf-8')) # 原样返回给发送者 skt.sendto(recv_data, client_addr) if recv_data == b'byebye': break skt.close()
import socket skt = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) while True: data = input('>>>:') # 向指定主机发送数据 skt.sendto(data.encode('utf-8'), ('10.8.152.52', 9999)) # 接收服务器发来的数据 recv_data, server_addr = skt.recvfrom(1024) print(server_addr, recv_data.decode('utf-8')) if recv_data == b'byebye': break skt.close()