1

I've set up a python client and server with socket in Python, that allows the server to send text to the client and I've been trying to extend it so that images can be sent to the client.

Server code:

import socket

#setup and bind server socket
s_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#setup socket
s_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)#reuses same port (allows reconnection)
s_socket.bind(('192.168.178.52', 9001))

s_socket.listen(1)

#connects and prints clients data and send message
clientsocket, address = s_socket.accept()
print('Connection from {}'.format(address))
clientsocket.send(bytes('Welcome to the server', 'utf-8'))

#Loops for server to sent text data to client


while True:
    m = input('Enter')
    try:
        file = open(m, 'rb')
        b = file.read(2048)
        clientsocket.send(b)
    except:
        clientsocket.send(bytes(m, 'utf-8'))

Client code:

import socket
import webbrowser
import os
import pyautogui

#setup and bind client socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect(('----------', 9001))#ip swapped for post

while True:
    message = s.recv(2048)#recieves all messages sent with buffer size
    if message:
        txt = str(message)
        with open('plswork.png', 'wb') as file:
            file.write(message)
            file.close()

The problem I'm having is that it will send the file over and create it perfectly fine, but only part of the image will load in when i open it (see image) I am pretty sure this is something to do with the buffer size however when I increase it, it wont recognise the file at all and I'll get an error trying to open the photo (preferably you would be able to send most photos). New to python sockets so any help would be appreciated!

(at the moment trying to send a pic of tux...)

https://i.stack.imgur.com/lBblq.png

Zack Turner
  • 216
  • 3
  • 14
andypaling1
  • 142
  • 12
  • The linked photo appears blank to me. – AMC Mar 14 '20 at 00:05
  • AMC opening ok for me, all it is was the penguin but only an 8th of it actually there. – andypaling1 Mar 14 '20 at 00:37
  • `message = s.recv(2048)#recieves all messages sent with buffer size` - It does not. All what it does is receive at most 2048 byte. Which might be all what the client has send or only parts of it (rest comes with more `recv`). Similar `send` sends at most the data but you need to check how many data were actually sent or use `sendall` instead. Also, are all your files less than 2048 byte in the first place? – Steffen Ullrich Mar 14 '20 at 10:42
  • no more reaction on this question. Do you need further clarifications? Is my answser not helpful? – gelonida Apr 20 '20 at 11:59

1 Answers1

1

I don't know the size of the file, but shouldn't you read the file until it is read completely and send data in chunks?

while True:
    m = input('Enter')
    try:
        file = open(m, 'rb')
        while True:
            b = file.read(2048)
            if not b:
                break
            clientsocket.send(b)
    except:
        clientsocket.send(bytes(m, 'utf-8'))

Client side had to be adapted as well.

Most network protocols add more information to simplify reception.

It could for example be a good idea, if you first send the number of bytes, that the welcome message contains, then the welcome message, then some indicator, that you will send a file, then some information, how many bytes you will send for the image and only then the bytes of the image

You will also find out, that it is complicated for the client to know what is the text message and what is part of the png file.

In fact if you would remove the input() command from the server and hard code a file name you might probably notice. that the welcome message and the png file could arrive combined at the client side. and it would have difficulties separating the two.

So to make your code robust, there's a lot of work to do.

gelonida
  • 5,327
  • 2
  • 23
  • 41