JeremyK
JeremyK

Reputation: 155

How to reuse same socket in Python (error 10048, 10061 etc)

I checked many socket questions and I can't find answer how to write this code correctly I want server socket to keep listening and working but if I'll run client more than once on the same active server I keep getting errors. When I tried to modify code I mostly recieved 10048 and 10061 socket errno or Windows UAC error(which was evaded by changing port number from standard 80). I know that I should remove .close or break loop but whatever else I put there keeps giving me new errors instead. How this code should look like so server could keep listening to new clients?

Client

# Echo client program
import socket

host = '192.168.1.3'      # The remote host
port = 50007              # The same port as used by the server

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

Server

# Echo server program
import socket

HOST = ''                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)
conn.close()

Expected output: Connected by ('192.168.1.3', 51019) <- more than once

Upvotes: 0

Views: 1336

Answers (1)

tdelaney
tdelaney

Reputation: 77347

In the server, you only call accept once so you will never service more than one client request. You could increase the connection request backlog and do your accepts in an outer while:

import socket

HOST = ''                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)
while 1:
    conn, addr = s.accept()
    print 'Connected by', addr
    conn.settimeout(1.0) # give client 1 second to talk to us
    while 1:
        try:
            data = conn.recv(1024)
            if not data:
                break
            conn.send(data)
        except socket.timeout:
            break
    conn.shutdown(socket.SHUT_RDWR)
    conn.close()

(notice I also shutdown the connection to make sure that it is cleaned up before closing). You may start to loose connections if clients are coming in faster than the the inner while can do the echo. But servers need some way to throttle clients and this is a reasonable way to handle things in a simple single threaded server. A malicious client could hang the server completely by connecting and then not sending anything so I added a timeout.

Upvotes: 2

Related Questions