程序在套接字交互期间挂起
我有两个程序,sendfile.py 和 recvfile.py,它们应该交互以通过网络发送文件。它们通过 TCP 套接字进行通信。通信应该是这样的:
sender =====filename=====> receiver
sender <===== 'ok' ======= receiver
or
sender <===== 'no' ======= receiver
if ok:
sender ====== file ======> receiver
我已经有了
发送者和接收者代码在这里:
发送者:
import sys
from jmm_sockets import *
if len(sys.argv) != 4:
print "Usage:", sys.argv[0], "<host> <port> <filename>"
sys.exit(1)
s = getClientSocket(sys.argv[1], int(sys.argv[2]))
try:
f = open(sys.argv[3])
except IOError, msg:
print "couldn't open file"
sys.exit(1)
# send filename
s.send(sys.argv[3])
# receive 'ok'
buffer = None
response = str()
while 1:
buffer = s.recv(1)
if buffer == '':
break
else:
response = response + buffer
if response == 'ok':
print 'receiver acknowledged receipt of filename'
# send file
s.send(f.read())
elif response == 'no':
print "receiver doesn't want the file"
# cleanup
f.close()
s.close()
接收者:
from jmm_sockets import *
s = getServerSocket(None, 16001)
conn, addr = s.accept()
buffer = None
filename = str()
# receive filename
while 1:
buffer = conn.recv(1)
if buffer == '':
break
else:
filename = filename + buffer
print "sender wants to send", filename, "is that ok?"
user_choice = raw_input("ok/no: ")
if user_choice == 'ok':
# send ok
conn.send('ok')
#receive file
data = str()
while 1:
buffer = conn.recv(1)
if buffer=='':
break
else:
data = data + buffer
print data
else:
conn.send('no')
conn.close()
我确信我在死锁中遗漏了一些东西,但不知道它是什么是。
I have two programs, sendfile.py and recvfile.py that are supposed to interact to send a file across the network. They communicate over TCP sockets. The communication is supposed to go something like this:
sender =====filename=====> receiver
sender <===== 'ok' ======= receiver
or
sender <===== 'no' ======= receiver
if ok:
sender ====== file ======> receiver
I've got
The sender and receiver code is here:
Sender:
import sys
from jmm_sockets import *
if len(sys.argv) != 4:
print "Usage:", sys.argv[0], "<host> <port> <filename>"
sys.exit(1)
s = getClientSocket(sys.argv[1], int(sys.argv[2]))
try:
f = open(sys.argv[3])
except IOError, msg:
print "couldn't open file"
sys.exit(1)
# send filename
s.send(sys.argv[3])
# receive 'ok'
buffer = None
response = str()
while 1:
buffer = s.recv(1)
if buffer == '':
break
else:
response = response + buffer
if response == 'ok':
print 'receiver acknowledged receipt of filename'
# send file
s.send(f.read())
elif response == 'no':
print "receiver doesn't want the file"
# cleanup
f.close()
s.close()
Receiver:
from jmm_sockets import *
s = getServerSocket(None, 16001)
conn, addr = s.accept()
buffer = None
filename = str()
# receive filename
while 1:
buffer = conn.recv(1)
if buffer == '':
break
else:
filename = filename + buffer
print "sender wants to send", filename, "is that ok?"
user_choice = raw_input("ok/no: ")
if user_choice == 'ok':
# send ok
conn.send('ok')
#receive file
data = str()
while 1:
buffer = conn.recv(1)
if buffer=='':
break
else:
data = data + buffer
print data
else:
conn.send('no')
conn.close()
I'm sure I'm missing something here in the sorts of a deadlock, but don't know what it is.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于阻塞套接字(这是默认设置,我假设您正在使用它(无法确定,因为您使用的是神秘模块
jmm_sockets
)),recv
方法是阻塞的——当它“暂时没有什么可返回的”时,它不会返回空字符串,正如您似乎假设的那样。您可以解决此问题,例如,通过在要发送的实际字符串之后发送显式终止符(绝不能出现在文件名中),例如
'\xff'
,然后等待它位于另一端,表明所有字符串现已收到。With blocking sockets, which are the default and I assume are what you're using (can't be sure since you're using a mysterious module
jmm_sockets
), therecv
method is blocking -- it will not return an empty string when it has "nothing more to return for the moment", as you seem to assume.You could work around this, for example, by sending an explicit terminator character (that must never occur within a filename), e.g.
'\xff'
, after the actual string you want to send, and waiting for it at the other end as the indication that all the string has now been received.TCP 是一种流式传输协议。它没有消息边界的概念。对于阻塞套接字, recv(n) 将返回仅当发送方关闭套接字或显式调用 shutdown 时,零长度字符串(SHUT_WR)。否则,它可以返回长度从 1 到 n 个字节的字符串,并且将阻塞,直到至少有一个字节要返回。
您可以设计一个协议来确定何时获得完整的消息。几种方法是:
您可能面临的另一个问题是 send() 不是保证发送所有数据。返回值指示实际发送了多少字节,发送者有责任继续调用 send 来发送剩余的消息字节,直到它们全部发送为止。您可能更愿意使用 sendall() 方法。
TCP is a streaming protocol. It has no concept of message boundaries. For a blocking socket, recv(n) will return a zero-length string only when the sender has closed the socket or explicitly called shutdown(SHUT_WR). Otherwise it can return a string from one to n bytes in length, and will block until it has at least one byte to return.
It is up to you to design a protocol to determine when you have a complete message. A few ways are:
Another issue you may face is that send() is not guaranteed to send all the data. The return value indicates how many bytes were actually sent, and it is the sender's responsibility to keep calling send with the remaining message bytes until they are all sent. You may rather use the sendall() method.