1. Três elementos de comunicação de rede
(1) endereço IP
(2) Número da porta
(3) Protocolo de transmissão
2. Processo de comunicação de soquete baseado no protocolo TCP
Introdução ao processo:
(1) O servidor cria um soquete de acordo com o tipo de endereço, tipo de soquete e tipo de protocolo (você pode imaginar que o soquete é um banco)
(2) Ligue o ip e o número da porta ao soquete (você pode imaginar que o IP é o endereço do banco e o número da porta é o número da casa)
(3) O socket do servidor escuta a requisição do número da porta e está pronto para receber e processar requisições do cliente a qualquer momento. Neste momento, o socket do servidor não está aberto (pode-se imaginar que a porta do banco não está aberta, esperando o cliente chegar)
(4) O cliente cria um soquete
(5) O cliente abre o soquete, e então se conecta ao soquete do servidor de acordo com o IP do servidor e o número da porta (pode ser imaginado como se estivesse tentando abrir a porta do banco)
(6) Antes que o cliente solicite a conexão, o servidor está em um estado bloqueado. Após o soquete do servidor receber a solicitação de soquete do cliente, ele começa a abrir o soquete, e então cria um novo soquete (pode-se imaginar que o portão do banco está Fechado, ao solicitar atendimento, o banco abre a porta e cria uma janela de atendimento, ou seja, o novo soquete para atendimento aos clientes)
(7) Em seguida, comunique-se entre o servidor e o cliente
(8) O cliente desconecta e fecha
(9) O servidor está fechado (fechado é o novo soquete, que é a janela de serviço)
3. Comunicação de thread único
(1) Cliente:
# -*- encoding:utf-8 -*-
import os
import socket
"""
文件上传:客户端
"""
def post_file(sk_obj, file_path):
"""
上传文件
:param sk_obj: socket对象
:param file_path: 文件路径
:return:
"""
# 发送文件名qq.jpg
file_name = os.path.split(file_path)[1]
sk_obj.sendall(file_name.encode("utf-8"))
# 发送文件大小
file_size = os.stat(file_path).st_size
sk_obj.sendall(str(file_size).encode("utf-8"))
# 发送文件内容
with open(file_path, "rb") as f:
while file_size > 0:
sk_obj.sendall(f.read(1024))
file_size -= 1024
sk = socket.socket()
sk.connect(("127.0.0.1", 13000))
print("客户端上线了。。。。")
file_path = r"qq.jpg"
post_file(sk, file_path)
print("客户端发送图片数据给服务端")
sk.close()
(2) Servidor
# -*- encoding:utf-8 -*-
import socket
"""
文件上传:服务端
"""
def get_file(sk_obj):
"""
接收文件
:param sk_obj: socket对象
:return:
"""
# 接受文件名
file_name = sk_obj.recv(1024).decode("utf-8")
sk_obj.sendall(b"OK")
# 接受文件大小
file_size = int(sk_obj.recv(1024).decode("utf-8"))
sk_obj.sendall(b"OK")
# 接受文件内容
with open(file_name, "wb") as f:
while file_size > 0:
f.write(sk_obj.recv(1024))
file_size -= 1024
# 创建socket对象
sk = socket.socket()
# 为socket对象绑定ip和端口号
sk.bind(("127.0.0.1", 13000))
# 监听
sk.listen()
print("服务端启动了。。。。。")
# 等待传入连接
# 连接之前,处于等待状态
# 连接之后,会返回一个新的套接字和客户端ip地址
conn, address = sk.accept()
print("客户端IP地址为:", address)
get_file(conn)
print("服务端接收图片数据")
conn.close()
sk.close()