Jimit
Jimit

Reputation: 245

the code stuck after receiving one byte from the socket ?

In the code shown below I am using the blocking call to receive 50 bytes of data from socket and echo it back.But what is happening is that the code stuck after receiving one byte.In the telnet running on another command prompt the connection still shows as connected. What might be missing from this ?

import socket
import sys

host = ''
port = 8888

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

s.bind((host,port))
print 'Socket Bind Complete'

s.listen(10)
print 'Now Listening'

while 1:
   conn, adr = s.accept()
   print 'connected with' + adr[0] + ':' + str(adr[1])
   data = conn.recv(50)
   print data
   if not data:
    break
   conn.sendall(data)

conn.close()
s.close() 

Upvotes: 1

Views: 1318

Answers (1)

abarnert
abarnert

Reputation: 365915

The problem is that you're accepting a new connection each time through the loop, and only receiving from that connection once. The next time through the loop, your forget about that connection and accept a new one, which blocks until someone else connects.


If you just want to handle a single connection and quit, just move the accept outside the loop:

conn, adr = s.accept()
print 'connected with' + adr[0] + ':' + str(adr[1])
while True:
    data = conn.recv(50)
    print data
    if not data:
        break
    conn.sendall(data)
conn.close()
s.close()

If you want to handle one connection at a time, but then wait for a new connection after you finish with the first, add an outer loop.

while True:
    conn, adr = s.accept()
    print 'connected with' + adr[0] + ':' + str(adr[1])
    while True:
        data = conn.recv(50)
        print data
        if not data:
            break
        conn.sendall(data)
    conn.close()
s.close()

If you want to handle more than one connection at a time, as most servers do, you need some sort of asynchronous mechanism—select and nonblocking sockets, gevent, threads, whatever. For example:

def handle_client(conn, addr):
    print 'connected with' + adr[0] + ':' + str(adr[1])
    while True:
        data = conn.recv(50)
        print data
        if not data:
            break
        conn.sendall(data)
    conn.close()

client_threads = []
try:
    while True:
        conn, adr = s.accept()
        client_thread = threading.Thread(target=handle_client, args=[conn, addr])
        client_thread.start()
        client_threads.append(client_thread)
finally:
    s.close()
    for client_thread in client_threads:
        client_thread.join()

In any of these designs, you're probably better off using a with statement instead of explicit close calls and/or try/finally.

Upvotes: 1

Related Questions