如何使用Python中的套接字在两个设备之间发送数据?

时间:2019-07-16 13:38:48

标签: python sockets networking

我正在为客户端使用以下代码:

import socket

HOST = "Server IP"
PORT = 5555

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))
s.close()

服务器的以下代码:

import socket

HOST = "Client IP"
PORT = 5555

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
print('Connected by', addr)
while True:
    data = conn.recv(1024)
    if not data:
        break
    conn.sendall(data)
    s.close()

我想做的只是将一些数据从设备发送到另一个设备。问题是我可以通过在同一网络上的设备上发送数据来使它工作(也就是说,将数据从CMD窗口发送到另一个,或者将数据从PC发送到手机,在其中安装了Termux和Python的地方,如果PC和手机连接到同一网络)。

但是,如何在两个不同的网络之间发送数据?我想应该在客户端的HOST变量中放置服务器的公共IP地址,而在服务器端的HOST变量中应该放置客户端的公共IP地址,对吗? 但是,然后假设在客户端网络中连接了许多设备,我该在哪里指定客户端的私有IP地址以将数据发送到特定设备?

2 个答案:

答案 0 :(得分:2)

简短的答案是,您不能-如今连接到Internet的大多数路由器都包括防火墙和/或NAT,这两个路由器都是专门设计用来防止来自外部世界的Internet数据包到达Internet上的设备的。出于安全原因,本地LAN。特别是,分配给LAN上的设备(192.168.1.510.0.0.10等)的专用地址是不可路由的,因此在以下情况下它们是没有意义的:本地网络,不能用于在Internet上路由流量。

但是,显然这并不是完整的答案,因为当今使用的各种点对点程序(例如Skype)确实可以按照您想要的方式进行通信;但是,他们都必须以一种或另一种方式解决上述问题。他们采取的一些方法包括:

  1. 让要接收传入TCP连接的LAN用户在其路由器上配置端口转发。这告诉路由器,在特定端口上收到的任何TCP连接都应自动转发到LAN上的指定专用IP地址。这种方法的缺点是,它在用户的防火墙中打开了一个漏洞,以后可能会被不良行为者利用,并且许多用户不愿意(甚至无法)以这种方式重新配置路由器。

  2. 运行带有面向Internet的IP地址的服务器,并使您的程序始终连接到该服务器。然后,该服务器可以用作代理,根据需要将TCP数据从一个连接转发到另一个。这样可以避免此问题,但必须维护自己的24/7面向公众的服务器并通过它路由所有流量。

  3. 使用TCP hole punching来说服路由器允许您的传入TCP连接,方法是利用它们(有时)用来决定何时允许传入流量的规则/逻辑。这将为您提供所需的直接连接,但设置起来相当复杂,无法在所有路由器上正常工作,并且通常需要执行步骤(2)(上述)作为前提条件,因为连接引导过程本身需要某些必须由第三方协助的通信。

答案 1 :(得分:0)

要工作,请将s.listen()更改为s.listen(5)

我能够从网络192.168。 1 .x连接到其他192.168。 2 .x

现在,根据您的要求,您将需要一些配置才能在Internet中工作。

如果服务器应用程序为:

,客户端应具有取决于服务器本地化的IP。

  • 直接连接到Internet,客户端应具有网关IP地址
  • 连接到路由器,您可以配置DMZ(不推荐,不安全,仅用于测试)或配置端口(安全和推荐),客户端应具有路由器的网关IP地址