我开始使用套接字发送文件。我了解到我可以通过套接字流发送1024个“块”,然后将其分解回服务器端。我将服务器设置为首先获取一个包含它将接收的文件大小的字符串,并在读取时进行比较以查看读取是否已完成。
客户端代码是:
BUFFER_SIZE = 1024
limit = os.path.getsize("test.db") #4096 bytes
currentamt = BUFFER_SIZE
f = open("test.db", "rb")
l = f.read(BUFFER_SIZE)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(str(limit)) #first, send the limit
while(1):
s.send(l)
if currentamt >= limit:
break
l = f.read(BUFFER_SIZE)
currentamt += BUFFER_SIZE
print "still sending.."
s.close()
print "Done."
服务器代码如下:
while True:
conn, addr = s.accept()
print "Connection address: ", addr
f = open('rec.db', 'wb')
while 1:
limit = conn.recv(20) #this will get your limit size
limit = limit.rstrip()
limit = float(limit) #error in question
print limit
l = conn.recv(BUFFER_SIZE) #get byte bufferred back
while (1):
if currentamt >= limit:
f.write(l)
break
f.write(l)
l = conn.recv(BUFFER_SIZE)
currentamt += BUFFER_SIZE
f.close() #close your file after you're done
conn.close()
s.close()
如果我将服务器中的限制从20更改为10,我可以转换为浮点数,但是在print语句后我得到一个错误!此外,打印限制在浮动(限制)语句之前有效,这使我感到困惑。
答案 0 :(得分:0)
TCP / IP保证您以正确的顺序获得正确的字节。它不保证您收到的块的大小。 IOW,如果你发送1024字节,1024字节,1024字节 - 那么就没有什么可以阻止TCP将其切换成512字节,512字节,512字节,512字节,512字节,512字节 - 甚至更奇怪的东西。它还保留聚合块的权利,形成2048字节,1024字节。
要解决这个问题,重要的是在发送和接收周围放置一个循环,或者使用能够更容易bufsock或扭曲的东西。就我个人而言,我认为扭曲使这更容易,但很多其他事情更难,但也许这只是因为我写了bufsock。
Bufsock位于http://stromberg.dnsalias.org/~strombrg/bufsock.html
在您的特定情况下,我看到您以ASCII发送长度,但我没有看到您发送任何类型的终止字符或填充到字段宽度。这将在连接的另一端受到严重破坏,它似乎假设长度总是20个字符长。要解决这个问题,您可以:
s.send(str(limit) + '\n')
...但是仍然存在缺少循环的问题。 Bufsock为你做循环,你只需要经常(足够)记住bufsock.flush()。