4

I am writing a multi-threaded client/server program. It splits a large file into smaller files in its client side and sends the smaller files to the server concurrently.

The problem is that in every run, the server can only receive two of the smaller files (the first one and another random one). Meanwhile, I encounter the error: "[Errno 32] Broken pipe" in client side of the program in s.sendall(part). The error arises in every thread that starts to send one of the smaller files before reception of the first file (on the server). In other words, every thread that starts to send after the reception the first file (on the server) can complete its task.

I run each of the client and server codes on different computers (both have the following specification: Ubuntu 14.04 desktop, 64 bit, 16GiB ram)

Client side Error:

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)

Server Side Error:

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()
Mahyar Hosseini
  • 131
  • 4
  • 12
  • From the error seems like there's a null byte somewhere in the string that's being converted to an int. I would try printing out the bytes in details (just to confirm). If the null byte is at the end of the string details[1].rstrip('\0') should take care of it. – junnytony May 27 '15 at 00:54
  • @junnytony Thank you :) It worked. But, I was wondering why two of the received numbers (converted from string to int) do not encounter with the same problem! – Mahyar Hosseini May 27 '15 at 01:11
  • I'm actually not sure why. I would definitely try printing out `data` just before converting to string and splitting, to see what the differences are. – junnytony May 27 '15 at 20:27

0 Answers0