Python 学习笔记-19

Python 学习笔记-19:

  1. Socket
  2. 粘包情况处理
  3. 模拟上传文件

1. Socket

服务器端 Socket 建立

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import socket

sk = socket.socket()
print(sk) # <socket.socket fd=448, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>

# 绑定端口
address = ('127.0.0.1', 8000)
sk.bind(address)
# 排队人数
sk.listen(3)

print('waiting...')
conn = sk.accept()
print(conn)
  • 客户端链接s
1
2
3
4
5
import socket

sk = socket.socket()
address = ('127.0.0.1', 8000)
sk.connect(address)
  • server下的方法
  1. bind()# 绑定端口
  2. listen()# 设置监听数
  3. accept()#
  4. recv()# 接收信息
  5. send()# 发送信息 必须为byte类型
  6. sendall()# 发送长信息
  7. close()# conn.close() 终止通话 sk.close()关闭端口
  • client下的方法
  1. connetc()# 连接
  2. recv()# 接收信息
  3. send()# 发送信息 必须为byte类型
  4. sendall()# 发送长信息
  5. close()#终止通话
  • 注意,在数据传输的过程中用的是client端的sk而非server端的sk

2. 粘包问题处理

1
2
# 在发送端添加一个recv
# 在接收端添加一个send

3. 模拟上传文件

  • 流程
    1. 建立链接
    1. 客户端选择上传文件
    1. 服务端接收上传文件
  • 客户端代码示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    import socket, os

    sk = socket.socket()
    address = ('127.0.0.1', 8000)
    sk.connect(address)
    # 获取文件夹路径
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))

    while True:
    # 输入上传方式和要上传的文件名
    inp = input('>>:').strip()
    # 分离命令和路径
    cmd, path = inp.split('|')
    # 路径拼接
    path = os.path.join(BASE_DIR, path)
    # 分别提取文件名,文件大小,文件信息
    file_name = os.path.basename(path)
    file_size = os.stat(path).st_size
    file_info = 'post|%s|%s' % (file_name, file_size)
    # 以固定格式发送文件信息
    sk.sendall(bytes(file_info, 'utf8'))

    # 读取要发送的文件的信息
    f = open(path, 'rb')
    # 已经发送的数据大小
    has_sent = 0
    while has_sent != file_size:
    # 使用f.read提取信息
    data = f.read(1024)
    sk.sendall(data)
    has_sent += len(data)

    f.close()
    print('上传成功')
  • 服务端代码示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import socket, os

    sk = socket.socket()
    address = ('127.0.0.1', 8000)
    sk.bind(address)
    sk.listen(3)
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))

    while 1:
    conn, addr = sk.accept()
    while 1:
    # 接收文件信息
    data = conn.recv(1024)
    # 以固定格式分离文件信息
    cmd, file_name, file_size = str(data, 'utf8').split('|')
    path = os.path.join(BASE_DIR, 'yuan', file_name)
    file_size = int(file_size)
    # 上传文件到指定位置
    f = open(path, 'ab')
    # 已经接收的文件大小
    has_receive = 0
    while has_receive != file_size:
    data = conn.recv(1024)
    f.write(data)
    has_receive += len(data)
    f.close()