Sending file over socket
Question: I'm have a problem sending data as a file from one end of a socket to the
other. What's happening is that both the server and client are trying to read
the file so the file never gets sent. I was wondering how to have the client
block until the server's completed reading the file sent from the client.

I have this working with raw packets using send and recv, but figured this was
a cleaner solution...

**Client:**

  1. connects to server creating socket connection
  2. creates a file on socket and sends data
  3. waits for file from server

**Server:**

  1. waits for file from client

**Complete interraction:**

  1. client sends data to server
  2. server sends data to client

Edit

The code I'm actually looking at was posted in this question, but I think the
Eventlet stuff scared people...
<http://stackoverflow.com/questions/2909358/eventlet-client-server>

Underneath its just using Python sockets so I figured I'd simplify the
question and ask about just the core socket issue...


Answer: It sounds like you have the client sending the file and then waiting for the
server response, but if you don't give the server an indication that it has
completely read the file, recv() on the server side will hang waiting for more
data. You can call shutdown(SHUT_WR) on the client-side once the client is
done sending. This informs the server that once it has read all the data sent
that there is no more.

A very basic example (sending one data blob to server and receiving one data
blob in response):

**server**

    
    
    >>> from socket import *
    >>> s=socket()
    >>> s.bind(('',8000))
    >>> s.listen(1)
    >>> c,a = s.accept()  # will hang here until a client connects
    >>> recvd=''
    >>> while True:
    ...  data = c.recv(1024)
    ...  if not data: break # recv() will return '' only if the client calls shutdown(SHUT_WR) or close()
    ...  recvd += data
    ...
    >>> recvd
    'a message'
    >>> c.sendall('a response')
    >>> c.close()  # done with client, could loop back to accept here
    >>> s.close()  # done with server
    

**client**

    
    
    >>> from socket import *
    >>> s=socket()
    >>> s.connect(('localhost',8000))
    >>> s.sendall('a message')
    >>> s.shutdown(SHUT_WR)  # tells server you're done sending, so recv won't wait for more
    >>> recvd=''
    >>> while True:
    ...  data = s.recv(1024)
    ...  if not data: break
    ...  recvd += data
    ...
    >>> recvd
    'a response'
    >>> s.close()
    

