python错误:[Errno 32] Socket.sendall()

时间:2015-05-27 00:04:30

标签: python sockets client-server python-multithreading socketserver

我正在编写一个多线程客户端/服务器程序。它将大文件拆分为客户端的较小文件,并将较小的文件同时发送到服务器。

问题在于,在每次运行中,服务器只能接收两个较小的文件(第一个和另一个随机的文件)。与此同时,我遇到了错误:" [Errno 32]断管"在s.sendall(part)中的程序的客户端。在接收第一个文件(在服务器上)之前,每个开始发送一个较小文件的线程都会出现错误。换句话说,在接收到第一个文件(在服务器上)之后开始发送的每个线程都可以完成其任务。

我在不同的计算机上运行每个客户端和服务器代码(两者都有以下规范:Ubuntu 14.04桌面,64位,16GiB ram)

客户端错误:

Traceback (most recent call last):
  File "Desktop/File_transmission/Client.py", line 56, in sendSplittedFile
    s.sendall(part)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 32] Broken pipe

Client.py:

import random
import socket
import time
import threading
import errno
import select
import File_manipulation
import sys, traceback

class Client:
    nodesIpAddr = ["....", "...."] #Server = ....
    dataPort = 45678
    delay = 2
    inputFileAddress = 'tosend.dat'
    fileOutputPrefix = 'output'
    fileOutputSuffix = ".dat"
    bufferSize = 2048
    max_size_splitted_file = 10*(2**20) # 10 MiB

    def __init__ (self, my_ip):
        self.ip = my_ip


    def send(self, ip_toSend, dataPort):         
        print "\tSend function is runing."
        totalNumSplittedFile = File_manipulation.split_file(Client.inputFileAddress, Client.fileOutputPrefix, Client.max_size_splitted_file , Client.bufferSize)
        for i in range(0, totalNumSplittedFile):
            thread_send = threading.Thread(target = self.sendSplittedFile, args = (ip_toSend, dataPort, Client.bufferSize, i, Client.fileOutputPrefix, totalNumSplittedFile))
                thread_send.start()  


    def sendSplittedFile(self, ip_toSend, dataPort, bufferSize, fileNumber, fileNamePrefix, totalNumSplittedFile):        
        # Create a socket (SOCK_STREAM means a TCP socket)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        BUFFER_SIZE = bufferSize

        try:
            s.connect((ip_toSend, dataPort))
            f = open(fileNamePrefix + '.%s' % fileNumber,'rb')
            s.send(str(fileNumber) + " " + str(totalNumSplittedFile))
            part = f.read(BUFFER_SIZE)
            while (part):
                s.sendall(part)
                part = f.read(BUFFER_SIZE)

            f.close()
            s.sendall(part)
            time.sleep(Client.delay)
            s.sendall('EOF')
            print "Done Sending."
            print s.recv(BUFFER_SIZE)
            s.close()
            print "\tData is sent to ", ip_toSend,

        except socket.error, v:
            traceback.print_exception(*sys.exc_info())           
        s.close()


nodeIP = [(s.connect(('8.8.8.8', 80)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]
n = Client(nodeIP)
n.send(n.nodesIpAddr[0], n.dataPort)

服务器端错误:

Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__
    self.handle()
  File "Desktop/File_transmissionServer.py", line 37, in handle
    totalFileNumber = int(details[1])
ValueError: null byte in argument for int()

Server.py

import socket
import time
import threading
import errno
import select
import SocketServer
import File_manipulation

class ServerThreadHandler(SocketServer.BaseRequestHandler):
    nodesIpAddr = ["....", "...."] #Server = ....
    fileOutputPrefix = 'torec '
    fileOutputSuffix = '.dat'
    dataPort = 45678
    delay = 3
    maxNumClientListenedTo = 200
    timeout_in_seconds = 5 
    bufferSize = 2048
    totalFileNumber = 0 #Total number of splitted files. It should be set by the incoming packets

    def handle(self):    
        BUFFER_SIZE = ServerThreadHandler.bufferSize  # Normally 1024, but we want fast response

        # self.request is the TCP socket connected to the client
        data = self.request.recv(BUFFER_SIZE)
        addr = self.client_address[0]

        details = str(data).split()
        currentFileNum = int(details[0])
        totalFileNumber = int(details[1])
        print '\tReceive: Connection address:', addr,'Current File Number: ', currentFileNum, 'Total Number of splitted files: ', totalFileNumber

        f = open(ServerThreadHandler.fileOutputPrefix + '_Received.%s' % currentFileNum, 'wb')
        data = self.request.recv(BUFFER_SIZE)
        while (data and data != 'EOF'):
            f.write(data)
            data = self.request.recv(BUFFER_SIZE)
        f.close()
        print "Done Receiving." ," File Number: ", currentFileNum
        self.request.sendall('\tThank you for data. File Number: ' + str(currentFileNum))

if __name__ == "__main__":
    HOST, PORT = ServerThreadHandler.nodesIpAddr[0], ServerThreadHandler.dataPort # HOST = "localhost"
    server = SocketServer.TCPServer((HOST, PORT), ServerThreadHandler)
    # Activate the server; this will keep running until you interrupt the program with Ctrl-C
    server.serve_forever()

0 个答案:

没有答案