TCP/UDP协议: TCP(Transmission Control Protocol)一种面向连接的、可靠的、传输层通信协议(比如:打电话) 优点:可靠,稳定,传输完整稳定,不限制数据大小 缺点:慢,效率低,占用系统资源高,
TCP(Transmission Control Protocol)一种面向连接的、可靠的、传输层通信协议(比如:打电话)
优点:可靠,稳定,传输完整稳定,不限制数据大小
缺点:慢,效率低,占用系统资源高,一发一收都需要对方确认
应用:Web浏览器,电子邮件,文件传输,大量数据传输的场景
面向连接无边界协议
UDP(User Datagram Protocol)一种无连接的,不可靠的传输层通信协议(比如:发短信)
优点:速度快,可以多人同时聊天,耗费资源少,不需要建立连接
缺点:不稳定,不能保证每次数据都能接收到
应用:IP电话,实时视频会议,聊天软件,少量数据传输的场景
面向非连接的有边界协议
客户端和服务端在建立连接时: 三次握手
客户端和服务端在断开连接时: 四次挥手
SYN 创建连接
ACK 确认响应
FIN 断开连接
socket的意义:通络通信过程中,信息拼接的工具(中文:套接字)
# 开发中,一个端口只对一个程序生效,在测试时,允许端口重复捆绑 (开发时删掉)
# 在bind方法之前加上这句话,可以让一个端口重复使用
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
TCP协议 TCP基本语法 客户端
1 import socket 2 # 1.创建一个socket对象 3 sk = socket.socket() 4 5 # 2.与服务端建立连接 6 sk.connect( ("127.0.0.1" , 9000) ) 7 8 # 3.收发数据的逻辑 9 """发送的数据类型是二进制字节流""" 10 """b开头的字符串是二进制字节流格式,要求字符类型必须是ascii编码""" 11 sk.send("今天我们学习网络编程".encode()) 12 13 # 接受数据 14 res = sk.recv(1024) 15 print(res.decode()) 16 # 4.关闭连接 17 sk.close()View Code 服务端
1 """ 2 一发一收是一对,不匹配会导致数据异常 3 send 发送 recv 接受 4 """ 5 import socket 6 7 # 1.创建一个socket对象 8 sk = socket.socket() 9 10 # 一个端口绑定多个程序(仅在测试时使用) 11 sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 12 13 # 2.在网络中注册该主机(绑定对应的ip和端口号) 14 """ 默认本地ip : 127.0.0.1 => localhost """ 15 sk.bind( ("127.0.0.1" , 9000) ) 16 # 3.开启监听 17 sk.listen() 18 19 # 4.三次握手 20 conn,addr = sk.accept() 21 22 # 5.收发数据的逻辑 23 24 # 接受数据 25 """一次最多接受1024个字节""" 26 res = conn.recv(1024) 27 print(res) 28 print(res.decode()) 29 30 # 发送数据 31 conn.send("好好学习,天天向上".encode()) 32 33 34 # 6.四次挥手 35 conn.close() 36 37 # 7.退还端口 38 sk.close()View Code TCP循环发消息 客户端
1 import socket 2 3 # (1) 创建socket对象 4 sk = socket.socket() 5 # (2) 连接服务端 6 sk.connect( ("127.0.0.1" , 9001) ) 7 # (3) 收发数据的逻辑 8 9 while True: 10 # 发送数据 11 strvar = input("[客户端]请输入您要发送的数据>>>") 12 sk.send(strvar.encode()) 13 14 # 接受数据 15 res = sk.recv(1024) 16 if res == b"q": 17 break 18 print(res.decode()) 19 # (4) 关闭连接 20 sk.close()View Code 服务端
1 import socket 2 3 # (1) 创建socket对象 4 sk = socket.socket() 5 6 # 一个端口绑定多个程序(仅在测试时使用) 7 sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 8 9 # (2) 在网络中注册该主机(绑定ip和端口号) 10 sk.bind( ("127.0.0.1" , 9001) ) 11 # (3) 监听端口 12 sk.listen() 13 # (4) 三次握手 14 # conn,addr = sk.accept() 15 # (5) 收发数据的逻辑 16 17 """ 18 print(conn) 19 print(addr) 20 <socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 50176)> 21 ('127.0.0.1', 50176) 22 """ 23 24 while True: 25 conn,addr = sk.accept() 26 while True: 27 # 接受数据 28 res = conn.recv(1024) 29 print(res.decode()) 30 31 # 发送数据 32 strvar = input("[服务端]请输入您要发送的数据>>>") 33 conn.send(strvar.encode()) 34 35 # 退出 36 if strvar == "q": 37 break 38 39 40 # (6) 四次挥手 41 conn.close() 42 43 # (7) 退还端口 44 sk.close()View Code
UDP协议
UDP基本语法
客户端
1 import socket 2 3 # 1.创建udp对象 4 sk = socket.socket(type=socket.SOCK_DGRAM) 5 6 # 2.收发数据的逻辑 7 # 发送数据 8 msg = "你喜欢我么~" 9 # sendto( 二进制字节流 , ip端口号 ) 10 sk.sendto( msg.encode() , ("127.0.0.1",9000) ) 11 12 # 接受数据 13 msg , addr = sk.recvfrom(1024) 14 print(msg.decode()) 15 print(addr) 16 17 # 3.关闭连接 18 sk.close()View Code 服务端
1 import socket 2 3 # 1.创建udp对象 4 sk = socket.socket(type=socket.SOCK_DGRAM) 5 6 # 2.在网络中注册该主机(绑定ip和端口号) 7 sk.bind( ("127.0.0.1",9000) ) 8 9 # 3.收发数据的逻辑 10 """udp协议下,默认第一次只能接收数据(没有三次握手,不清楚对方的ip和端口号)""" 11 # 接受数据 12 msg , addr = sk.recvfrom(1024) 13 print(msg.decode()) 14 print(addr) 15 16 # 发送数据 17 sk.sendto( "我喜欢你个锤子".encode() , addr ) 18 19 # 4.关闭连接 20 sk.close()View Code
UDP循环发消息 客户端
1 import socket 2 3 sk = socket.socket(type=socket.SOCK_DGRAM) 4 5 while True: 6 # 发送数据 7 strvar = input("[客户端]请输入您要发送的内容>>>") 8 sk.sendto( strvar.encode() , ("127.0.0.1",9000) ) 9 10 # 接受数据 11 msg , addr = sk.recvfrom(1024) 12 print(msg.decode()) 13 14 sk.close()View Code 服务端
1 import socket 2 3 sk = socket.socket(type=socket.SOCK_DGRAM) 4 sk.bind( ("127.0.0.1",9000) ) 5 6 while True: 7 # 接受数据 8 msg , addr = sk.recvfrom(1024) 9 print(msg.decode()) 10 print(addr) 11 12 # 发送数据 13 strvar = input("[服务端]请输入您要发送的内容>>>") 14 sk.sendto( strvar.encode() , addr) 15 sk.close()View Code