Search code examples
pythonsockets

Error trying to pass (large) image over socket in python


I am trying to pass an image over python socket for smaller images it works fine but for larger images it gives error as

socket.error: [Errno 10040] A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself

I am using

socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

Thanks for any clue .

I tried using SOCK_STREAM, it does not work .. It just says me starting ... and hangs out . with no output .. Its not coming out of send function

import thread
import socket
import ImageGrab

class p2p:
    def __init__(self):
        socket.setdefaulttimeout(50)
        #send port
        self.send_port = 3000
        #receive port
        self.recv_port=2000

        #OUR IP HERE
        self.peerid = '127.0.0.1:'
        #DESTINATION 
        self.recv_peers = '127.0.0.1'

        #declaring sender socket
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM )
        self.socket.bind(('127.0.0.1', self.send_port))
        self.socket.settimeout(50)

        #receiver socket
        self.serverSocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM )
        self.serverSocket.bind(('127.0.0.1', self.recv_port))
        self.serverSocket.settimeout(50)

        #starting thread for reception
        thread.start_new_thread(self.receiveData, ())

        #grabbing screenshot
        image = ImageGrab.grab()
        image.save("c:\\test.jpg")
        f = open("c:\\ test.jpg", "rb")
        data = f.read()
        #sending
        self.sendData(data)
        print 'sent...'
        f.close()

        while 1: pass

    def receiveData(self):
        f = open("c:\\received.png","wb")
        while 1:
            data,address = self.serverSocket.recvfrom(1024)
            if not data: break
            f.write(data)
        try:
            f.close()
        except:
            print 'could not save'
        print "received"
    def sendData(self,data):
        self.socket.sendto(data, (self.recv_peers,self.recv_port))
if __name__=='__main__':
    print 'Started......'    
    p2p()

Solution

  • Your image is too big to be sent in one UDP packet. You need to split the image data into several packets that are sent individually.

    If you don't have a special reason to use UDP you could also use TCP by specifying socket.SOCK_STREAM instead of socket.SOCK_DGRAM. There you don't have to worry about packet sizes and ordering.