RPC over TCP 与同一台机器上的多个客户端

Posted

技术标签:

【中文标题】RPC over TCP 与同一台机器上的多个客户端【英文标题】:RPC over TCP with multiple clients on same machine 【发布时间】:2018-07-25 21:22:23 【问题描述】:

我正在使用 msgpack 在 golang 中构建一个 RPC 服务器。 客户端是使用 mprpc 库(msgpack over TCP 和 gevent)在 python 中构建的。

我的问题是,作为网络中的绝对菜鸟,我发现我不能在同一台计算机上同时运行多个客户端使用相同的地址/端口(我猜套接字已经绑定,它只是停止和超时) .

我环顾四周,但我不确定我应该怎么做才能让同一台机器上的多个客户端与服务器通信(msgpack 来回)。这是我需要使用 ZeroMQ 的情况吗?还是通过 HTTP 请求?

谢谢!

【问题讨论】:

【参考方案1】:

TCP 是一种面向连接的协议。这意味着只有服务器需要有一个固定的、已知的端口。客户端可以使用它想要的任何端口,因为没有人与客户端建立连接。

那么,服务器如何知道如何与客户端通信?每当它接受一个连接时,它就会被告知连接来自谁。但通常情况下,您甚至不需要它,因为套接字会跟踪连接的来源。只需在该套接字上接收并发送,您就可以与正确的客户端交谈。


您可能应该阅读 Python 文档中的 Socket Programming HOWTO 或其他一些教程,但要简短...

一个服务器是这样启动的:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', 12345))
sock.listen(5)
while True:
    csock, addr = sock.accept()

binds 一个端口和listens 并围绕accepting 连接并使用它们做一些事情。

另一方面,客户只是这样做:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 12345))

……或者,等效地:

sock = socket.create_connection(('localhost', 12345))

它不调用bind,它只是创建一个连接,让套接字库在该连接的适当接口上选择一个任意端口。除非您已经打开了数千个套接字,否则它应该始终能够为您找到空闲端口。

【讨论】:

非常感谢您的回答!那么这是否意味着,在同一台计算机上,我应该能够从不同的进程多次调用 socket.create_connection(('localhost', 12345)) ? @Tuft 是的,你应该能够运行数百个程序(或者同一个程序并行运行数百次),它们都调用socket.create_connection(('localhost', 12345)),它们都可以工作(每个程序都会自动运行)获得一个独特的端口来连接)。【参考方案2】:

如果你想有双向连接,那么 HTTP 不适合这个。因为HTTP被设计成服务器只响应请求,这阻止了服务器自己发出请求。还有其他解决方案提供两种方式的连接(服务器到客户端和客户端到服务器同时)。

WebSocket 是我首先想到的。当然ZeroMQ也可以做到这一点。

【讨论】:

谢谢!我只是想向服务器发送一个请求,然后返回响应,我猜不是真的双向?

以上是关于RPC over TCP 与同一台机器上的多个客户端的主要内容,如果未能解决你的问题,请参考以下文章

同一台机器上的IPC...WCF

无法从另一台机器连接到 Geth 节点 RPC

在同一台开发机器上运行多个 Netty 客户端和服务器

ip地址/子网掩码/默认网关/DNS服务器/DHCP服务器/WINS服务器/NetBIOS over TCP/IP

RPC

Java TCP Socket编程:客户端和服务器在同一台计算机上通信良好,但无法通过局域网相互发送数据