首页 > 解决方案 > 使用python在持久tcp上进行多个文件传输

问题描述

我正在尝试通过 python 中的持久 TCP 连接传输多个图像。据我所知,这段代码应该可以正常工作,但有时会显示以下错误 ValueError: invalid literal for int() with base 10: '6789:'

对于每个图像,我首先尝试将该图像的大小发送给客户端。

有人可以帮助我解决我做错的事情,或者以其他方式指导如何做到这一点

服务器代码

import socket                   
import time
import os

port = 6004              
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)             
host = socket.gethostname()     # Get local machine name
s.bind((host, port))            # Bind to the port
s.listen(5)                     # Now wait for client connection.

print ('Server listening....')
conn, addr = s.accept()
print ('Got connection from', addr)
# data = conn.recv(1024)
# print('Server received', repr(data))

start =time.time()

for i in range(2):
    filename="sc" + str(i) + ".jpg"
    size = str(os.path.getsize(filename))
    try:
        conn.send(size.encode())
    except:
        print('ckckckckckck')
    print('filesize', size, len(size))
    f = open(filename,'rb')
    current=0
    size = int(size)
    while current <size:
       l = f.read(1024)
       conn.send(l)
       current+=len(l)
       print('current',current)
       print('l',len(l))
       if(current==size):
        break
    print('close current',current)
    f.close()

print('Done sending')
conn.send(b'Thank you for connecting')
#conn.close()
print(time.time()-start)

客户端代码

import os
import socket 
import time                 # Import socket module

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)             # Create a socket object
host = socket.gethostname()     # Get local machine name
port = 6004               # Reserve a port for your service.

s.connect((host, port))
s.send(b'Hello server!')

for i in range(2):
    data = None
    data = s.recv(1024)
    data = data.decode()
    size = int(data)
    print(size)
    filename = "sc" + str(i) + ".jpg"
    f = open(filename,'wb')
    current =0
    while current<size:
        data = s.recv(1024)
        f.write(data)
        current+=len(data)
        # print('data',len(data))
        # print('current',current)
        if(current==size):
            break
    print('close current',current)
    f.close()
print('Successfully get the file')
s.close()
print('connection closed')

标签: python-3.xsockets

解决方案


  data = s.recv(5)

您希望大小在前 5 个字节内,并且您希望用一个来获得它recv。但是,实际大小可能小于 5 个字节或更多,因为您在发送时不强制执行特定数量的字节:

    conn.send(size.encode())

因此,这里可能发生的情况是您在客户端读取的大小太小(如果原始大小较大)或者使用的大小少于 5 个字节,并且在您读取的 5 个字节内已经有来自文件内容的数据. 这会导致您看到的错误。

请注意,TCP 是字节流协议,而不是消息协议,这意味着你send的东西不一定是你recv的。取而代之的是,可以在一个内读取来自多个的数据,send也可以在一个内读取recv多个send数据recv。因此,更好的代码设计将确保它始终为长度写入固定长度,并始终确保在尝试将数据解释为长度之前获得完整长度。


推荐阅读