I’m trying to make a program in python that implements sockets. Each client sends a PDF file and the server receives it and the title is changed to “file_(number).pdf” (e.g.: file_1.pdf). The problem presented is that only a client can send a file successfully. When a second client tries to send the file, the program crashes. What am I doing wrong and how can I solve my code to allow N clients (with N < 20) to connect to the server and transfer files?

Here’s the server code:

import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10) # Accepts up to 10 incoming connections..
sc, address = s.accept()

print address
i=1
f = open('file_'+ str(i)+".pdf",'wb') # Open in binary
i=i+1
while (True):

    # We receive and write to the file.
    l = sc.recv(1024)
    while (l):
        f.write(l)
        l = sc.recv(1024)
f.close()

sc.close()
s.close()

Here’s the client code:

import socket
import sys

s = socket.socket()
s.connect(("localhost",9999))
f = open ("libroR.pdf", "rb")
l = f.read(1024)
while (l):
    s.send(l)
    l = f.read(1024)
s.close()

To simplify my code, I always use a book with file name “libroR.pdf”, but in the full code it is chosen by a GUI.

You must put all the code from sc, address = s.accept() upto sc.close() into another loop or the server simply terminates after receiving the first file. It doesn’t crash, the script is just finished.

[EDIT] Here is the revised code:

import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10) # Accepts up to 10 connections.

while True:
    sc, address = s.accept()

    print address
    i=1
    f = open('file_'+ str(i)+".pdf",'wb') #open in binary
    i=i+1
    while (True):       
    # receive data and write it to file
        l = sc.recv(1024)
        while (l):
                f.write(l)
                l = sc.recv(1024)
    f.close()


    sc.close()

s.close()

Note that s.listen(10) means “set maximum accept rate to 10 connections“, not “stop after 10 connections”.

Your code is getting stuck in the second while loop.

See:

import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10)

i=1

while True:
    sc, address = s.accept()

    print address

    f = open('file_'+str(i)+".pdf",'wb') #open in binary
    i=i+1
    print(i)
    l = 1
    while(l):
        l = sc.recv(1024)
        while (l):
            f.write(l)
            l = sc.recv(1024)
        f.close()


    sc.close()

s.close()

Server:

import socket
from threading import Thread

TCP_IP = 'localhost'
TCP_PORT = 9001
BUFFER_SIZE = 1024


class ClientThread(Thread):

    def __init__(self, ip, port, sock):
        Thread.__init__(self)
        self.ip = ip
        self.port = port
        self.sock = sock
        print(" New thread started for "+ip+":"+str(port))

    def run(self):
        filename="anon234.jpeg"
        f = open(filename, 'rb')
        while True:
            l = f.read(BUFFER_SIZE)
            while (l):
                self.sock.send(l)
                #print('Sent ',repr(l))
                l = f.read(BUFFER_SIZE)
            if not l:
                f.close()
                self.sock.close()
                break


tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((TCP_IP, TCP_PORT))
threads = []

while True:
    tcpsock.listen(5)
    print("Waiting for incoming connections...")
    (conn, (ip, port)) = tcpsock.accept()
    print('Got connection from ', (ip, port))
    newthread = ClientThread(ip, port, conn)
    newthread.start()
    threads.append(newthread)

for t in threads:
    t.join()

Client:

import socket
import time

TCP_IP = 'localhost'
TCP_PORT = 9001
BUFFER_SIZE = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
recived_f="imgt_thread"+str(time.time()).split('.')[0]+'.jpeg'
with open(recived_f, 'wb') as f:
    print('file opened')
    while True:
        #print('receiving data...')
        data = s.recv(BUFFER_SIZE)
        print('data=%s', (data))
        if not data:
            f.close()
            print('file close()')
            break
        # write data to a file
        f.write(data)

print('Successfully get the file')
s.close()
print('connection closed')

You are closing the server socket (s in your code) after handling the first client connection. Thus only one client is ever handled by your server. Make a loop around accept and reading from the sc.

Using this code you can send files multiple time using the same client.py

Server.py

import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10) # Acepta hasta 10 conexiones entrantes.

i = 1
while True:
    sc, address = s.accept()

    print address
    f = open('file_'+ str(i)+".wav",'wb') #open in binary
    i=i+1
    while (True):
        # recibimos y escribimos en el fichero
        l = sc.recv(1024)
        f.write(l)

        if not l:
            break

    f.close()
    sc.close()
    print('copied the file.')

s.close()