1.网络通信三要素
(1)IP地址
(2)端口号
(3)传输协议
2.基于TCP协议的socket通信流程
流程介绍:
(1)服务端根据地址类型,socket类型和协议类型创建socket(可以想象socket是一个银行)
(2)为socket绑定ip和端口号(可以想象IP为银行地址,端口号为门牌号)
(3)服务器socket监听端口号请求,随时准备接收和处理客户端请求,这个时候服务端的socket没有打开(可以想象为银行的大门没有打开,等待客户上门)
(4)客户端创建socket
(5)客户端打开socket,然后根据服务器的IP和端口号,去连接服务器的socket(可以想象为试图打开银行的大门)
(6)客户端请求连接之前,服务端处于堵塞状态,服务端socket接收到客户端socket请求后,开始打开socket,然后创建新的套接字(可以想象为客户未请求服务之前,银行大门是关闭的,请求服务时,银行打开大门,创建服务窗口,也就是那个新的套接字,用于服务客户)
(7)然后服务端和客户端之间进行通信
(8)客户端断开连接,关闭
(9)服务端关闭(关闭的是新的套接字,也就是服务的窗口)
3.单线程通信
(1)客户端:
# -*- 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)服务端
# -*- 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()