我有一个简单的文件传输套接字程序,其中一个套接字发送文件数据,另一个套接字接收数据并写入文件
从目的地到源的转移完成后,我需要发送确认
目的地代码
s.accept()
f = s.makefile()
f.read(1024)
来源代码
s.connect(('localhost',6090))
f = s.makefile()
f.write('abcd')
f.flush()
出现问题,因为“abcd”不是1024字节,目标将阻塞直到收到1024字节
解决方案是关闭()套接字,但由于我需要来自目的地的确认,我无法关闭套接字。
如何告诉目的地停止阻止?我在想写一个EOF角色
我在网上读到“\ x04”是EOF,但它不起作用。
由于数据可能是二进制的,我不想使用readline()方法。
答案 0 :(得分:7)
设计协议(客户端和服务器之间的协议),了解如何发送消息。一种简单的方法是“第一个字节是消息的长度,后跟消息”。粗略的例子:
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from socket import *
>>> s=socket()
>>> s.connect(('localhost',5000))
>>> f=s.makefile()
>>> f.write('\x04abcd')
>>> f.flush()
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from socket import *
>>> s=socket()
>>> s.bind(('localhost',5000))
>>> s.listen(1)
>>> c,a=s.accept()
>>> f=c.makefile()
>>> length=ord(f.read(1))
>>> f.read(length)
'abcd'
答案 1 :(得分:2)
从套接字写入和读取是分开的。您可以尝试关闭套接字进行写入,并将其打开以供阅读。
请参阅http://docs.python.org/library/socket.html#socket.socket.shutdown
此外,FTP的作用是使用两个套接字:一个用于数据,另一个用于“确认”。
使用第二个套接字来获取这些额外的元数据会更快乐。
答案 2 :(得分:2)
如果您打算通过管道发送任何二进制数据,实际上并不想使用'EOF'标记。如果您的二进制数据恰好包含该字节序列会发生什么?您可以“逃避”它以防止这种情况发生,但这需要您检查两端,然后确保您也逃脱了转义序列。
如果您正在为某种生产系统执行此操作,请查看是否有可以使用的网络API(如FTP,HTTP,SFTP等)。
如果这是一所学校或小型项目,您需要做的是编写通信协议。最简单的可能是发送方广播单个二进制整数X(选择数据大小,并坚持使用它),然后发送X字节的二进制数据。接收器首先阻止大小,然后只期望接收该数量的数据。请记住,如果您需要发送的字节数超过X可以发送的数据大小,则需要“分块”数据。
还要考虑在传输过程中丢失通信时会发生什么。您可以在read()上设置超时,但是如果在超时后立即恢复通信,则需要优雅地恢复(尽管可能会认为所有数据都是正常的,具体取决于系统)。