程序在套接字交互期间挂起

发布于 2024-09-03 11:42:14 字数 1785 浏览 6 评论 0原文

我有两个程序,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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

↙温凉少女 2024-09-10 11:42:14

对于阻塞套接字(这是默认设置,我假设您正在使用它(无法确定,因为您使用的是神秘模块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), the recv 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.

眼睛会笑 2024-09-10 11:42:14

TCP 是一种流式传输协议。它没有消息边界的概念。对于阻塞套接字, recv(n) 将返回仅当发送方关闭套接字或显式调用 shutdown 时,零长度字符串(SHUT_WR)。否则,它可以返回长度从 1 到 n 个字节的字符串,并且将阻塞,直到至少有一个字节要返回。

您可以设计一个协议来确定何时获得完整的消息。几种方法是:

  1. 使用固定长度的消息。
  2. 发送指示总消息长度的固定长度消息,后跟消息的可变部分。
  3. 发送消息,后跟消息中绝不会出现的唯一终止消息。

您可能面临的另一个问题是 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:

  1. Use a fixed-length message.
  2. Send a fixed-length message indicating the total message length, followed by the variable portion of the message.
  3. Send the message, followed by a unique termination message that will never occur in the message.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文