大佬教程收集整理的这篇文章主要介绍了使 pynng 和 socket 相互通信,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用 pynng
启动了服务器,然后来自 Python 标准库 socket
的客户端将尝试向其发送消息。
问题是客户端可以发送消息,但服务器却没有注意到。因此,它不起作用。
我错过了什么吗?一些低级协议设置?一些终止符?
我这样做的原因是我将构建一个使用 pynng
作为服务器的 Python 脚本。然后一个非 Python 程序(我假设它了解基本的 TCP 协议)将尝试与这个 Python 服务器通信。因此,我使用了恕我直言我可以操作的最原始的套接字库,即标准库中的 socket
模块。
我将在讨论时展示代码片段,但我会在最后展示完整的最小代码示例。
我正在尝试使用 pynng
def server():
with pynng.Pair0(Listen=f'tcp://{HOST:s}:{PORT:D}',recv_timeout=10000) as s:
print("Server running")
data = s.recv() # Blocks forever here
print(data)
然后,看起来像这样的客户端将尝试连接到它:
def clIEnt():
with socket.create_connection(address=(HOST,PORT),timeout=5) as s:
print("ClIEnt connected")
s.sendall(b'Hello world')
print("ClIEnt sent message")
我将它们放在一起使用 threading
:
def main():
srv = threading.Thread(target=server)
cli = threading.Thread(target=clIEnt)
srv.start()
cli.start()
srv.join()
cli.join()
总而言之,这是最低限度的工作代码:
import socket
import pynng
import threading
HOST = "127.0.0.1"
PORT = 65432
def main():
srv = threading.Thread(target=server)
cli = threading.Thread(target=clIEnt)
srv.start()
cli.start()
srv.join()
cli.join()
def server():
with pynng.Pair0(Listen=f'tcp://{HOST:s}:{PORT:D}',recv_timeout=10000) as s:
print("Server running")
data = s.recv() # Blocks forever here
print("message received")
print(data)
def clIEnt():
with socket.create_connection(address=(HOST,timeout=5) as s:
print("ClIEnt connected")
s.sendall(b'Hello world')
print("ClIEnt sent message")
if __name__ == "__main__":
main()
然后我在终端运行这个
$ python main.py
似乎 server
无法recv
发送消息,因此 recv
尝试在 10000 毫秒时超时。
Server running
ClIEnt connected
ClIEnt sent message
Exception in thread Thread-1:
TraceBACk (most recent call last):
file "/home/kmonisit/miniconda3/envs/engg/lib/python3.8/threading.py",line 932,in _bootstrap_inner
self.run()
file "/home/kmonisit/miniconda3/envs/engg/lib/python3.8/threading.py",line 870,in run
self._target(*self._args,**self._kwargs)
file "main.py",line 39,in server
data = s.recv() # Blocks forever here
file "/home/kmonisit/miniconda3/envs/engg/lib/python3.8/site-packages/pynng/nng.py",line 454,in recv
check_err(ret)
file "/home/kmonisit/miniconda3/envs/engg/lib/python3.8/site-packages/pynng/exceptions.py",line 201,in check_err
raise exc(String,err)
pynng.exceptions.Timeout: Timed out
pynng 基于 Nanomsg Next Generation,它是 Scalability Protocols 的实现。可扩展性协议适用于许多不同的传输,包括 tcp,但裸 sockets 不兼容。但是,通过一点祈祷和肘部润滑脂,它们可以兼容。也就是说,如果需要,您可以在纯 Python 中实现可扩展性协议。
首先,我们需要知道wire格式是什么;谢天谢地,in an RFC in the original nanomsg repository 已记录在案。 Pair0
客户端的实现如下:
class Pair0:
"""A poor implementation of the Pair0 protocol"""
def __init__(self,host,port,timeout=NonE):
self._sock = socket.create_connection(address=(host,port),timeout=timeout)
# https://github.com/nanomsg/nanomsg/blob/master/rfc/sp-tcp-mapping-01.txt
# upon making a connection,both ends are required to send this header
self._sock.send(b'\x00SP\x00\x00\x10\x00\x00')
print(self._sock.recv(8))
def send(self,data):
# messages are simply "length + payload". Length is 64-bit in network byte
# order.
packed = struct.pack('!Q',len(data))
self._sock.sendall(packed + data)
def recv(self):
size_bytes = self._sock.recv(8)
(size,) = struct.unpack('!Q',size_bytes)
received = 0
parts = []
while received < size:
data = self._sock.recv(size - received)
received += len(data)
parts.append(data)
return b''.join(parts)
并集成到您的测试程序中:
import socket
import struct
import pynng
import threading
import time
HOST = "127.0.0.1"
PORT = 65432
def main():
srv = threading.Thread(target=server)
srv.start()
# sleep to give the server time to bind to the address
time.sleep(0.1)
_client = Pair0(HOST,PORT,1)
_client.send(b'Hello pynng')
_client.send(b'hope everything is going well for you')
print(_client.recv())
print(_client.recv())
srv.join()
def server():
with pynng.Pair0(listen=f'tcp://{HOST:s}:{PORT:D}',recv_timeout=1000) as s:
print("Server running")
for _ in range(2):
data = s.recv()
print("message received")
print(data)
s.send(b'Hello bad client')
s.send(b'I hope you are doing okay')
class Pair0:
"""A poor implementation of the Pair0 protocol"""
def __init__(self,size_bytes)
received = 0
parts = []
while received < size:
data = self._sock.recv(size - received)
received += len(data)
parts.append(data)
return b''.join(parts)
if __name__ == "__main__":
main()
现在,这远不及 pynng 中的实现(它依赖于底层的 nng 实现)那么健壮。 nng 在边缘条件下执行 The Right Thing™,包括丢失网络、处理多个客户端、跟踪状态机、处理 SIGINT 等。这也是一个不完整的实现,因为它没有 bind
等。>
免责声明:我是 pynng 的作者。
以上是大佬教程为你收集整理的使 pynng 和 socket 相互通信全部内容,希望文章能够帮你解决使 pynng 和 socket 相互通信所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。