这是一个非常出乎意料的行为:
这是一个教科书上的经典短程序,它使用一个线程从套接字流中逐个获取字符并显示它,第二个线程读取输入并通过相同的套接字流发送输入。
导入套接字导入线程导入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
发布于 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_NODELAY
是1
,而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
。
https://stackoverflow.com/questions/51603244
复制相似问题