如何使用 Python 中的套接字在两个设备之间发送数据? [英] How send data between two devices using sockets in Python?

查看:39
本文介绍了如何使用 Python 中的套接字在两个设备之间发送数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using this code for the client:

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和手机连接到同一网络)

and what I'd like to do is simply send some data from a device to another. The problem is that I could make it work just by sending data on devices on the same network (that is, send data from a CMD window to another, or send data from the PC to the phone, where I have Termux with Python installed, if the PC and the phone are connected to the same network).

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

However, how do I send data between two different networks? I suppose that in the HOST variable on the client side I should put the public IP address of the server and in the HOST variable on server side I should put the public IP address of the client right? But then suppose that in the client network there are many devices connected, where do I specify the private IP address of the client to send the data to a specific device?

推荐答案

简短的回答是你不能——现在大多数连接到 Internet 的路由器都包含防火墙和/或 NAT,这两者都是明确设计的出于安全原因,防止来自外部世界的 Internet 数据包到达本地 LAN 上的设备.特别是,分配给 LAN 上设备的私有地址(192.168.1.510.0.0.10 等)不可路由,因此它们在本地网络环境之外没有意义,并且不能用于通过 Internet 路由流量.

The short answer is that you can't -- most routers connected to the Internet these days include a firewall and/or NAT, both of which are explicitly designed to prevent Internet packets from the outside world from getting to devices on the local LAN, for security reasons. In particular, the private addresses assigned to devices on the LAN (192.168.1.5, 10.0.0.10, and so on) are non-routable, so they are not meaningful outside the context of the local network and cannot be used to route traffic across the Internet.

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

Obviously that's not the full answer, though, since various peer-to-peer programs in use today (e.g. Skype) do manage to communicate in the way you want to do; however, they all have to work around the above problem one way or another. Some ways they do it include:

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

  1. Have the user of the LAN that is to receive the incoming TCP connection configure port forwarding on his router. This tells the router that any TCP connections received on a particular port should be automatically forwarded to the specified private IP address on the LAN. Downsides of this approach are that it opens a hole in the user's firewall that might be later exploited by bad actors, and that many users aren't willing (or even able) to reconfigure their routers in this way.

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

Run a server with an Internet-facing IP address, and have your program always connect to it. This server can then work as a proxy, forwarding TCP data from one connection to the other as necessary. This avoids the problem, at the cost of having to maintain your own 24/7 public-facing server and route all your traffic through it.

使用TCP打孔来说服路由器允许您通过利用它们(有时)用来决定何时允许传入流量的规则/逻辑来阻止传入的 TCP 连接.这为您提供了您想要的直接连接,但设置相当复杂,不适用于所有路由器,并且通常需要将步骤 (2)(以上)作为先决条件,因为连接引导过程本身需要某些必须由第三方促成的通信.

Use TCP hole punching to convince the router(s) to allow your incoming TCP connections by exploiting the rules/logic they (sometimes) use to decide when to allow incoming traffic. This gets you the direct connections you want, but it's fairly complicated to set up, doesn't work on all routers, and generally requires the implementation of step (2) (above) as a prerequisite, since the connection-bootstrapping process itself requires some communication that must be facilitated by a third-party.

这篇关于如何使用 Python 中的套接字在两个设备之间发送数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆