Отправка картинок на Socket Python - PullRequest
1 голос
/ 12 апреля 2020

Я сейчас работаю над проектом, и мне нужно отправить фотографию на другой компьютер через Python. Я использую модуль Socket, но когда я попытался отправить свою фотографию, я получил сообщение об ошибке «Сообщение, отправленное на сокет датаграммы, было больше внутреннего буфера сообщений или другой границы сети, или буфер, используемый для получения дейтаграммы, был меньше самой дейтаграммы "Как это исправить? Спасибо

Ответы [ 2 ]

1 голос
/ 12 апреля 2020

Ваше изображение слишком велико для отправки в одном UDP-пакете. Вам необходимо разделить данные изображения на несколько пакетов, которые отправляются индивидуально. socket.SOCK_STREAM вместо socket.SOCK_DGRAM. Там вам не нужно беспокоиться о размерах пакетов и порядке. Хотя вам нужно установить buffer_size.

import random
import socket, select
from time import gmtime, strftime
from random import randint

imgcounter = 1
basename = "image%s.png"

HOST = '127.0.0.1'
PORT = 6666

connected_clients_sockets = []

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(10)

connected_clients_sockets.append(server_socket)
buffer_size = 4096

while True:

    read_sockets, write_sockets, error_sockets = select.select(connected_clients_sockets, [], [])



    for sock in read_sockets:

        if sock == server_socket:

            sockfd, client_address = server_socket.accept()
            connected_clients_sockets.append(sockfd)

        else:
            try:
                print ' Buffer size is %s' % buffer_size
                data = sock.recv(buffer_size)
                txt = str(data)

                if txt.startswith('SIZE'):
                    tmp = txt.split()
                    size = int(tmp[1])

                    print 'got size'
                    print 'size is %s' % size

                    sock.send("GOT SIZE")
                    # Now set the buffer size for the image 
                    buffer_size = 40960000

                elif txt.startswith('BYE'):
                    sock.shutdown()

                elif data:

                    myfile = open(basename % imgcounter, 'wb')

                    # data = sock.recv(buffer_size)
                    if not data:
                        myfile.close()
                        break
                    myfile.write(data)
                    myfile.close()

                    sock.send("GOT IMAGE")
                    buffer_size = 4096
                    sock.shutdown()
            except:
                sock.close()
                connected_clients_sockets.remove(sock)
                continue
        imgcounter += 1
server_socket.close()
0 голосов
/ 12 апреля 2020

Код сервера:

import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 5005))
server_socket.listen(5)
import os


client_socket, address = server_socket.accept()
print "Conencted to - ",address,"\n"
while (1):
    choice = client_socket.recv(1024)
    choice = int(choice)
    if(choice == 1):
        data = client_socket.recv(1024)
        print "The following data was received - ",data
        print "Opening file - ",data
        fp = open(data,'rb')
        strng = fp.read()
        size = os.path.getsize(data)
        size = str(size)
        client_socket.send(size)
        client_socket.send (strng)
        #client_socket.close()

    if (choice == 2 or choice == 3):
        data = client_socket.recv(1024)
        print "The following data was received - ",data
        print "Opening file - ",data
        img = open(data,'rb')
        while True:
            strng = img.read(512)
            if not strng:
                break
            client_socket.send(strng)
        img.close()
        print "Data sent successfully"
        exit()

Код клиента:

См. https://docs.python.org/2/library/socket.html#socket .socket.setblocking Этот код будет приостановлен до получения данных. По умолчанию все сокеты находятся в режиме блокировки. Вы должны сделать это неблокирующим.

В неблокирующем режиме, если вызов recv () не находит никаких данных или если вызов send () не может немедленно избавиться от данные, возникает исключение ошибки; в режиме блокировки вызовы блокируются, пока они не могут продолжаться. s.setblocking (0) эквивалентно s.settimeout (0.0); s.setblocking (1) эквивалентно s.settimeout (Нет).

Или:

положить client_socket.settimeout (10.0) после while (1) и перед client_socket.send (k) написать после while (1) -> c, a = client_socket.accept () c .settimeout (10.0) -> затем после этого, где бы ни находился client_socket, изменить его на "c"

Поэтому:

client_socket.connect(("", 5005))
deadline = time.time() + 20.0
client_socket.settimeout(deadline - time.time())
#or
client_socket.setblocking(0)

Весь код:

import socket,os
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("", 5005))
client_socket.settimeout(1.0)
k = ' '
size = 1024

while(1):
    print "Do you want to transfer a \n1.Text File\n2.Image\n3.Video\n"
    k = raw_input()
    client_socket.send(k)
    k = int (k)
    if(k == 1):
        print "Enter file name\n"
        strng = raw_input()
        client_socket.send(strng)
        size = client_socket.recv(1024)
        size = int(size)
        print "The file size is - ",size," bytes"
        size = size*2
        strng = client_socket.recv(size)
        print "\nThe contents of that file - "
        print strng

    if (k==2 or k==3):
        print "Enter file name of the image with extentsion (example: filename.jpg,filename.png or if a video file then filename.mpg etc) - "
        fname = raw_input()
        client_socket.send(fname)
        fname = 'documents/'+fname
        fp = open(fname,'w')
        while True:
            try:
                strng = client_socket.recv(512)
                if not strng:
                    break
            except timeout:
                continue
            fp.write(strng)
        fp.close()
        print "Data Received successfully"
        exit()
...