我开始使用套接字发送文件。我了解到我可以通过套接字流发送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,则可以转换为浮点数,但是在打印语句后出现错误!另外,打印限制确实在float(limit)语句之前起作用,这使我感到困惑。
最佳答案
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()。