简体   繁体   中英

Sending file over socket

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... https://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...

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()

I'm not sure the question is clear, are you asking:

  1. How to send an entire file's worth of data across a socket?
  2. How to get a writer to block after writing some data?
  3. Something else altogether??

If the question is #1, you need to open the file and parse it into a stream of bytes and then pass the entire collection of bytes in a single 'write' call.

If the question is #2, meaning you want the writer to wait until the reader has completely read the bytes (and processed them??) before moving on, then you need the reader and writer to coordinate. You can do this by having the writer call 'read' (read is a blocking call) after writing. Then after the reader is done reading (and processing the bytes) have it write something to the writer to wake it up.

If the question is #3, maybe you can provide some more details.

I'm not exactly clear on what you're asking, but perhaps you are looking for select ?

http://docs.python.org/library/select.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM