5

Do you know why this loop doesn't break?

#!/usr/bin/env python

from socket import *
import os
import sys

if __name__ == '__main__':
 HOST = '127.0.0.1'
 PORT = 55554

 print 'Creating socket'
 socketProxy = socket(AF_INET, SOCK_STREAM)

 print 'bind()'
 socketProxy.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
 socketProxy.bind((HOST, PORT))

 print 'Waiting for connection request'
 socketProxy.listen(1)
 conn, addr = socketProxy.accept()

 print 'Connected to ', addr

 request = ''

 while True:
    data = conn.recv(16);
    if not data: break
    request = request+data


print request
sys.stdout.flush()

I am writing a little Server-Proxy getting requests that can be arbitrary long so I must wait until I have received all the request. Anyway this loop (when len(data) == 0) doesn't stop and it keeps on waiting. How Can I stop it? Thanks

SagittariusA
  • 5,289
  • 15
  • 73
  • 127
  • 3
    The client doesn't shutdown/close the socket, maybe? – Lev Levitsky Feb 13 '13 at 13:12
  • 1
    Are you sure it doesn't simply hangs at `conn.recv(16)` because socket does not recieve any data? – sloth Feb 13 '13 at 13:12
  • Yes, the client doesn't close the socket because then it waits for the answer... – SagittariusA Feb 13 '13 at 13:17
  • 2
    Remember that sockets are _blocking_ by default, so if there is nothing to receive, then `recv` will block and wait. – Some programmer dude Feb 13 '13 at 13:39
  • I know...the problem is that client and server are given by our teacher, then we must write a proxy. when the client sends the request (an http similar request), it doesn't close the socket...and waits for answers. the proxy must get the html page from the server and send it to the client. So, to get the request from the client without blocking, Shall I perform a recv(n) and decide for a n quite big? – SagittariusA Feb 13 '13 at 13:50
  • How does the server know, that the client finished sending its request? What is the protocol? – Daniel Jun 24 '21 at 18:39

2 Answers2

3

One solution is to make the socket non-blocking. Then you receive in a loop until no more data is received. If no data has been received (i.e. request is empty) then the connection has been closed, otherwise you have your request.

When you have your request, send it on to the actual server, and do the same as above when waiting for the reply. Send the reply on to the client.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Shall I use MSG_DONTWAIT to make the socket not blocking? – SagittariusA Feb 13 '13 at 18:01
  • 1
    @user1576208 Or use the [`socket.setblocking`](http://docs.python.org/2/library/socket.html#socket.socket.setblocking) method. – Some programmer dude Feb 13 '13 at 19:25
  • The client can take some time to send any data to the socket, which means the connection isn't closed but no data is received at the time recv() is called. You should make sure the protocol have some way of detecting via a message whenever the client is terminating connection. – wallabra Jun 09 '16 at 23:08
1

You can try setting a timeout, see Python socket recv data in while loop not stopping

K.S.
  • 2,846
  • 4
  • 24
  • 32