【问题标题】:programs hangs during socket interaction程序在套接字交互期间挂起
【发布时间】:2010-05-25 00:56:13
【问题描述】:

我有两个程序,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()

我确定我在某种僵局中遗漏了一些东西,但不知道它是什么。

【问题讨论】:

    标签: python sockets network-programming communication-protocol


    【解决方案1】:

    使用阻塞套接字,这是默认的,我假设是你正在使用的(不能确定,因为你使用的是一个神秘的模块 jmm_sockets),recv 方法是阻塞的——它会当它“暂时没有更多内容可返回”时,不要返回一个空字符串,正如您所假设的那样。

    您可以解决此问题,例如,通过发送明确的终止符(绝不能出现在文件名中),例如'\xff',在您要发送的实际字符串之后,并在另一端等待它作为指示现在已收到所有字符串。

    【讨论】:

      【解决方案2】:

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

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

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

      您可能面临的另一个问题是send() 不能保证发送所有数据。返回值表示实际发送了多少字节,发送方有责任继续调用 send 并使用剩余的消息字节,直到它们全部发送完毕。您可能更愿意使用sendall() 方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-12
        • 1970-01-01
        相关资源
        最近更新 更多