通过套接字发送文件
我在通过套接字从一端发送文件到另一端时遇到了问题。现在的情况是,服务器和客户端都在尝试读取文件,所以文件根本没有被发送。我想知道如何让客户端在服务器完成读取客户端发送的文件之前先等待。
我用原始数据包通过send和recv实现了这个功能,但我觉得这样做会更简洁一些……
客户端:
- 连接到服务器,建立套接字连接
- 在套接字上创建一个文件并发送数据
- 等待服务器发送的文件
服务器:
- 等待客户端发送的文件
完整的交互过程:
- 客户端将数据发送给服务器
- 服务器将数据发送给客户端
编辑
我实际上在看的代码是这个问题中发布的,但我觉得Eventlet的内容让人有些害怕……https://stackoverflow.com/questions/2909358/eventlet-client-server
其实它只是使用了Python的套接字,所以我想我可以简化一下问题,专注于核心的套接字问题……
3 个回答
我不太明白你在问什么,但也许你是在找 select
这个东西?
我不太确定这个问题是否清楚,你是在问:
- 如何通过一个套接字发送整个文件的数据?
- 如何让写入操作在写入一些数据后暂停?
- 还是其他什么问题??
如果问题是第一个,你需要打开文件,把它的内容转换成一串字节,然后在一次'写入'操作中把所有字节一起发送出去。
如果问题是第二个,也就是说你希望写入操作在读入方完全读取(并处理)这些字节之前暂停,那么你需要让读入方和写入方进行协调。你可以让写入方在写完数据后调用'read'(read是一个会阻塞的调用)。然后在读入方读取完(并处理完字节)后,让它给写入方发送一些信息来唤醒它。
如果问题是第三个,或许你可以提供更多的细节。
听起来你是让客户端发送文件,然后等待服务器的回应。但是,如果你没有告诉服务器它已经完全读取了文件,服务器那边的recv()就会一直卡在那里,等着更多的数据。你可以在客户端发送完数据后调用shutdown(SHUT_WR)。这样可以告诉服务器,一旦它读取完所有发送的数据,就没有更多的数据了。
下面是一个非常简单的例子(发送一个数据块到服务器,并接收一个数据块作为回应):
服务器
>>> 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
客户端
>>> 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()