1. TCP通信
1.1 TCP协议与UDP协议的区别
项目 | tcp协议 | udp协议 |
---|---|---|
连接方面 | 面向连接的 | 面向无连接 |
安全方面 | 传输消息可靠、不丢失、按顺序到达 | 无法保证不丢包 |
传输效率方面 | 传输效率相对较低 | 传输效率高 |
连接对象数量方面 | 只能是点对点、一对一 | 支持一对一、一对多、多对多的交互通信 |
1.2 socket对象的常用方法
方法名称 | 功能描述 |
---|---|
bind((ip,port)) | 绑定IP地址和端口 |
listen(N) | 开始TCP监听,N表示 操作系统扶起的最大连接数量,取值 范围1-5之间,一般设置为5 |
accept() | 被动接收TCP客户端连接,阻塞式 |
connect((ip,port)) | 主动初始化TCP服务器连接 |
recv(size) | 接收TCP数据,返回值为字符串类型,size表示 要接收的最大数据量 |
send(str) | 发送TCP数据,返回值是要发送的字节数量 |
sendall(str) | 完整发送TCP数据,将str中的数据发送到连接的套接字,返回之前尝试发送所有数据,如果成功为None,失败抛出异常 |
recvfrom() | 接收UDP数据,返回值为一个元组(data,address),data表示 接收的数据,address表示 发送数据的套接字地址 |
sendto(data,(ip,port)) | 发送UDP数据,返回值是发送的字节数 |
close() | 关闭套接字 |
1.3 TCP服务器端流程
- 使用socket类创建一个套接字对象
- 使用bind((ip,port))方法绑定IP地址和端口号
- 使用listen()方法开始TCP监听
- 使用accept()方法等待客户端的连接
- 使用recv()/send()方法接收/发送数据
- 使用close()关闭套接字
import socket
# AF_INET用于internet之间在进程通信
# SOCK_STREAM 表示的是用TCP协议编程
#(1)创建socket对象
server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# (2)绑定IP地址和端口
ip='127.0.0.1'
port=8088
server_socket.bind((ip,port))
# (3)使用listen()方法开始TCP监听
server_socket.listen(5)
print('等待客户端连接')
# (4)使用accept()方法等待客户端的连接
client_socket,client_address=server_socket.accept()
# (5)使用recv()/send()方法接收/发送数据
res_data=client_socket.recv(1024).decode('utf-8')
while res_data!='bye':
if res_data!='':
print('收到来自客户端的数据:',res_data)
# 准备发送数据
data=input('请服务端输入要发送的数据:')
# 服务端回复客户端
client_socket.send(data.encode('utf-8'))
if data=='bye':
break
res_data=client_socket.recv(1024).decode('utf-8')
# (6)关闭socket
client_socket.close()
server_socket.close()
输出
等待客户端连接
收到来自客户端的数据: 你好,我是客户端
请服务端输入要发送的数据:你好,我是服务端
收到来自客户端的数据: 认识你很高兴
请服务端输入要发送的数据:我也是
1.4 TCP客户端的流程
- 使用socket类创建一个套接字对象
- 使用connect((host,port))设置连接的主机IP和主机设置的端口号
- 使用recv()/send()方法接收/发送数据
- 使用close()关闭套接字
import socket
# (1)使用socket类创建一个套接字对象
client_socket = socket.socket()
# (2)使用connect((host,port))设置连接的主机IP和主机设置的端口号,发送连接
client_socket.connect(('127.0.0.1', 8088))
print('已建立与服务器的连接')
# (3)使用recv()/send()方法接收/发送数据
info=''
while info!='bye':
# 准备发送的数据
send_data=input('请客户端输入要发送的数据:')
client_socket.send(send_data.encode('utf-8'))
# 判断
if send_data=='bye':
break # 退出循环
# 接收一条数据
info=client_socket.recv(1024).decode('utf-8')
print('收到来自服务器响应的数据:',info)
# (4)使用close()关闭套接字
client_socket.close()
输出
已建立与服务器的连接
请客户端输入要发送的数据:你好,我是客户端
收到来自服务器响应的数据: 你好,我是服务端
请客户端输入要发送的数据:认识你很高兴
收到来自服务器响应的数据: 我也是
请客户端输入要发送的数据:
2. UDP编程
2.1 发送方
from socket import socket, AF_INET, SOCK_DGRAM
# (1)创建socket对象
send_socket = socket(AF_INET, SOCK_DGRAM)
# (2)准备发送数据
data=input('请输入要发送的数据:')
# (3)指定接收方的IP地址和端口号
ip_port=('127.0.0.1',9999)
# (4)发送数据
send_socket.sendto(data.encode('utf-8'),ip_port)
# 接收来自接收方回复的数据
recv_data,addr = send_socket.recvfrom(1024)
print('addr=',addr)
print('接收到的数据为:',recv_data.decode('utf-8'))
# (5)关闭socket对象
send_socket.close()
2.2 接收方
from socket import socket, AF_INET, SOCK_DGRAM
#(1)创建socket对象
recv_socket = socket(AF_INET, SOCK_DGRAM)
#(2)绑定IP端口号
recv_socket.bind(('127.0.0.1', 9999))
#(3)接收来自发送方的数据
recv_data,addr=recv_socket.recvfrom(1024)
print('addr=',addr)
print('接收到的数据为:',recv_data.decode('utf-8'))
#(4)准备回复对方的数据
data=input('请输入要回复的数据:')
#(5)回复
recv_socket.sendto(data.encode('utf-8'),addr)