在Python中尝试通过套接字传输(大)图像时出错

1 投票
2 回答
9212 浏览
提问于 2025-04-15 14:26

我正在尝试通过Python的socket传输图片,对于小一点的图片,这个方法很好用,但对于大一点的图片就出错了,错误信息是:

socket.error: [Errno 10040] 发送到数据报socket的消息比内部消息缓冲区大,或者超过了其他网络限制,或者用于接收数据报的缓冲区比数据报本身小。

我使用的是:

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

谢谢你们提供的任何线索。

我尝试使用SOCK_STREAM,但没有成功……它只是告诉我开始了……然后就卡住了,没有任何输出……它一直停在发送函数里出不来。

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()

2 个回答

2

你发送的消息被截断了

因为你没有展示实际的 send 代码,所以我猜测你是在尝试将整个图片一次性发送到网络连接上。其实,你需要把图片分成几个小块来发送。

5

你的图片太大,不能在一个UDP数据包中发送。你需要把图片数据分成几个小的数据包,分别发送。

如果你没有特别的理由一定要用UDP的话,你也可以选择用TCP,只需要把socket.SOCK_STREAM替换成socket.SOCK_DGRAM就可以了。这样你就不用担心数据包的大小和顺序问题了。

撰写回答