NO.1 Python网络通信
零蚀
准备知识
-
虚拟机的网卡设置
- NAT网络地址转换模式:虚拟机和物理主机共用网络地址,(交换机并不会给他新的网络地址,它会得到一个)
- Bridge桥接模式:虚拟机和真实主机会有同网段的真实ip(可以和真实主机通信)
-
Parallels的桥接设置
保证虚拟机的IP地址和主机的IP地址不同,且虚拟机的地址不是10.xxx.xxx.xxx,10开头表示此虚拟机是NAT网络地址,和主机共用,所以要设置桥接模式,并且windows查看IP地址命令为ipconfig,mac查看ip地址命令为ifconfig。
状态栏点击应用图标,选择“配置”,进行如下的配置:
-
端口
- 物理端口:外接接口
- 虚拟端口:应用接口
端口号 0~65535 ,只有整数,
-
知名端口(0~1023)
常见端口 默认端口号 协议的基本作用 FTP 21 文件的上下传 SSH 22 安全的远程登录 TELNET 23 远程登录 SMTP 25 邮件传输 DNS 53 域名解析 HTTP 80 超文本协议 POP3 110 邮件接收 HTTPS 443 加密传输的HTTP -
注册端口(1024-49151)
- 三方应用所使用的指定端口
-
动态端口(49151~65535)
- 如果软件没有指定端口,系统会指定临时端口,用完收回
UDP
Udp是面向无链接的,用于不注重建立链接的方面,比如直播,广播通信等。在传输过程中会经常会发生丢包。
- 创建虚拟机UDP接收方
可以设置自己的IP地址和端口号,然后点击链接网络,别人发送的信息就可以接收到。
udp发送信息,代码如下:
# 设置ip地址的类型,ipv4 - socket.AF_INET
# 设置传输类型 udp (默认 socket.SOCK_STREAM --- TCP)
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# ip 192.168.101.27
# 形参一:data 要发送的数据的二进制形式 ,
# 形参二:(address,port)
udp_socket.sendto("来自回忆录".encode(), ("192.168.101.27", 6666))
udp_socket.close()
udp接收信息,代码如下:
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 每次发送信息,都会动态申请端口。
udp_socket.sendto("hello".encode(), ("192.168.101.27", 6666))
# bufsize 一次的信息处理大小 收到信息前会一直阻塞
recvfrom_data = udp_socket.recvfrom(1024)
print(recvfrom_data[0].decode(encoding="gbk")) # 蓦然回首,沙雕都在
print(recvfrom_data[1]) # ('192.168.101.27', 6666)
udp_socket.close()
# ---------------------控制台---------------------
# 蓦然回首,沙雕都在
# ('192.168.101.27', 6666)
编码解码:
绑定端口:
# 绑定端口号,pycharm 不再随机分配端口号
udp_socket.bind(("192.168.101.25", 3344))
- 全局广播:
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.bind(("192.168.101.25", 3344))
# SOL_SOCKET:当前socket,SO_BROADCAST : socket种类,add Permission
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
# need Permission
udp_socket.sendto("12点广播".encode(), ("255.255.255.255", 6666))
udp_socket.close()
TCP
-
TCP特点
- 面向连接
- 可靠传输
基于字节流的,传输层协议。
-
TCP编码
- 客户端
与udp不一样的是要创建链接
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立链接 tcp_socket.connect(("192.168.101.27", 6666)) # 发送数据,并等待接收数据 tcp_socket.send("TCP消息!!!".encode()) recv = tcp_socket.recv(1024) print(recv.decode()) tcp_socket.close()
- 服务器
由于可能有多个客户端连接到服务器上面,所以服务器等待客户端接入拿到发送的套接字对象,然后通过对象进行数据的接收。
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定端口号 tcp_socket.bind(("192.168.101.25", 3344)) # listen 将套接字主动链接变为被动 # 设置tcp的最大连接池(只在windows中有效,其他系统无效) tcp_socket.listen(128) # 阻塞等待连接 accept = tcp_socket.accept() """ (<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.101.25', 3344), raddr=('192.168.101.27', 49207)>, ('192.168.101.27', 49207) ) """ print(accept) """ 参数一 : socket的对象 参数二 : (address,port) """ print(accept[0]) # <socket.socket fd=4,..... print(accept[1]) # ('192.168.101.27', 49208) tcp_client_socket, id_port = accept # 需要用对方的socket来接收/发送data recv =tcp_client_socket.recv(1024) print(recv.decode(encoding="gbk")) tcp_client_socket.close() tcp_socket.close()
-
TCP文件下载
- client
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_socket.connect(("192.168.101.25", 6666)) file_name=input("输入文件名:\n") tcp_socket.send(file_name.encode()) with open("/Users/xx/Desktop/exercises","wb") as file: while True: recv = tcp_socket.recv(1024) if recv: file.write(recv) else: break tcp_socket.close()
- server
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_socket.bind(("192.168.101.25", 6666)) tcp_socket.listen(128) client, port = tcp_socket.accept() recv = client.recv(1024) with open("../story.txt", "rb") as file: while True: data = file.read(1024) if data: client.send(data.encode()) else: break client.close() tcp_socket.close()
🔗 前言
🔗 Python 高级列表
🔗 NO.2 Python Web 服务器
🔗 NO.3 Python多线程&锁
🔗 NO.4 Python多进程
🔗 NO.5 Python协程&生成器
🔗 NO.6 Python正则&爬虫初
🔗 NO.7 Python操作MySQL
🔗 NO.8 Python Spider
🔗 NO.9 Python 装饰器&other