TCP套接字文件传输
我正在用Python和AES写一个安全的文件传输程序,但遇到了一些我不太明白的问题。我把文件分成1024字节的小块发送,但接收数据的服务器崩溃了(因为我使用的是AES CBC,所以我的数据长度必须是16字节的倍数),而且我收到的错误提示说数据长度不对。
我尝试在客户端打印发送的数据长度和服务器接收到的数据长度,结果显示客户端每次确实发送了1024字节,正如预期的那样,但服务器那边显示在某个时刻接收到的数据包长度不是1024字节(比如743字节)。
我尝试在客户端每次发送数据之间加上time.sleep(0.5),结果似乎有效。难道这可能是服务器端的socket缓冲区出现问题?是不是客户端发送的数据太快,导致服务器的socket缓冲区崩溃,数据因此被损坏或丢失,recv(1024)只接收到了一部分数据?这是我能想到的唯一原因,但这也可能完全不对,如果有人知道为什么会这样,那就太好了;)
根据我的想法,我尝试了:
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32768000)
print socket.SO_RCVBUF
我在服务器端设置了一个32MB的缓冲区,但在Windows XP上打印出来是4098,而在Linux上只显示8。我不知道该怎么理解这个,唯一知道的是似乎没有32MB的缓冲区,所以代码无法正常工作。
这篇帖子真长,希望你们有耐心看到这里!我完全迷失了,如果有人对此有任何想法,请分享一下 :D
感谢Faisal,我的代码在这里:
服务器端:(count是我的文件大小/1024)
while 1:
txt=self.s.recv(1024)
if txt == " ":
break
txt = self.cipher.decrypt(txt)
if countbis == count:
txt = txt.rstrip()
tfile.write(txt)
countbis+=1
客户端:
while 1:
txt= tfile.read(1024)
if not txt:
self.s.send(" ")
break
txt += ' ' * (-len(txt) % 16)
txt = self.cipher.encrypt(txt)
self.s.send(txt)
提前谢谢大家,
Nolhian
8 个回答
正如其他人提到的,你可能正在处理一个不完整的信息。你需要要么使用固定大小的信息,要么使用一个分隔符(别忘了对你的数据进行转义!),这样你才能知道什么时候收到了完整的信息。
TCP是一种流协议,它不会保留消息的边界,就像你刚刚发现的那样。
欢迎来到网络编程的世界!你刚刚犯了一个大家第一次接触时都会有的误解,那就是认为客户端发送和服务器接收应该是对称的。其实并不是这样。操作系统允许接收数据的大小是可以变化的,可能会接收到不同大小的数据块。不过,这个问题其实很好解决,你只需要把数据缓冲起来,直到你读取的数据量和你想要接收的数据量相等。下面的代码可以帮你实现这个:
buff=''
while len(buff) < 1024:
buff += s.recv( 1024 - len(buff) )