首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如果使用getch,Python套接字recv是否等待发送?

如果使用getch,Python套接字recv是否等待发送?
EN

Stack Overflow用户
提问于 2018-07-31 06:43:38
回答 1查看 74关注 0票数 1

这是一个非常出乎意料的行为:

这是一个教科书上的经典短程序,它使用一个线程从套接字流中逐个获取字符并显示它,第二个线程读取输入并通过相同的套接字流发送输入。

导入套接字导入线程导入getch导入sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)

def rxWorker():
    while(True):
        r = s.recv(1)
        print(r.decode('ascii'), end='')

def txWorker():
    while (True):
        i = input('')
        s.send(i.encode())

s.connect(('localhost',9999))

threading.Thread(name='Rx', target=rxWorker).start()
threading.Thread(name='Tx', target=txWorker).start()

这对运行在不同终端上的netcat侦听器起作用:

nc -l localhost 9999

在这一点上,一切运行良好。线条从一边发送到另一边,并按预期显示。

现在输入被更改为immediate,所以python端发送键入的字符(而不是等待换行符),如下所示:

导入套接字导入线程导入getch导入sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)

def rxWorker():
    while(True):
        r = s.recv(1)
        print(r.decode('ascii'), end='')

def txWorker():
    while (True):
        # i = input('')
        i = getch.getche()
        s.send(i.encode())

s.connect(('localhost',9999))

threading.Thread(name='Rx', target=rxWorker).start()
threading.Thread(name='Tx', target=txWorker).start()

注意,唯一的变化是读取输入的方式:i = getch.getche()i = input('')

现在行为不同了。

来自python端的字符会立即正确地出现在netcat端。

问题:来自Netcat端的字符现在不会立即显示在python端。实际上,只有将一个或几个字符从python发送到netcat时才会显示。

这非常奇怪,有点破坏了我的控制流程/:

请指教

系统: Ubuntu 16.04,python 3.5.2

EN

回答 1

Stack Overflow用户

发布于 2018-07-31 08:26:35

主要问题是您还没有实际启用TCP_NODELAY

这一行并不做您认为它做的事情:

s = socket.socket(socket.AF_INET, socket.TCP_NODELAY )

socket的参数是:

socket.socket(family=AF_INET、type=SOCK_STREAM、proto=0、fileno=None)

碰巧的是,至少在*nix系统上,TCP_NODELAY1,而SOCK_STREAM是一个值为1的枚举,所以通过传递TCP_NODELAY作为类型,您选择的是SOCK_STREAM,也就是TCP。当socket库的未来版本切换到对sockopt值使用枚举时(就像它已经对类型所做的那样),这将成为一个TypeError,而不是默默地做一些偶尔发生的意想不到的事情。

如果您想启用像TCP_NODELAY这样的sockopt值,则必须在套接字上调用setsockopt。如下所示:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)

顺便说一句,您的代码中至少还有一个明显的错误,尽管它不会造成任何问题:

rxt = threading.Thread(name='Rx', target=rxWorker).start()

Thread.start返回None。因此,您可以看到rxt (和txt)到None。幸运的是,你实际上并没有对它们做任何事情--但是一旦你做了,比如rxt.join(),你就会得到一个AttributeError

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51603244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档