【问题标题】:How can I create a TCP connection in Python between 2 PCs如何在 Python 中创建两台 PC 之间的 TCP 连接
【发布时间】:2021-03-03 18:08:02
【问题描述】:

到目前为止,我已经制作了一个非常基本的客户端/服务器应用程序,它可以创建 TCP 连接。我有很多编程经验,只是从来没有做过这种低级的东西,尤其是网络方面的东西。请注意,所有的打印只是为了帮助我弄清楚发生了什么。一个已知的问题是 jsonip 有时会给我一个 IPv4 有时是 v6,我不知道为什么,但现在这并不重要,只是为了警告任何想要重新创建我的代码的人。

服务器:

import socket
import requests

port = int(input("Enter port you want to open:\n"))
#todo: add errorhandling
print("Adding socket...")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
hostname = socket.gethostname()
print(f"Hostname: {hostname}")
ip_address = socket.gethostbyname(hostname)
print(f"Host address: {ip_address}")
r = requests.get(r'http://jsonip.com')
public_ip_address = r.json()['ip']
s.bind((ip_address, port))
print("Is open for connections on IP: "+public_ip_address+" and Port: "+str(port))
s.listen(5)
print("Done initialisation, listening for incoming connections...")

while True:
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established")
    clientsocket.send(bytes(f"You have connected to server: {hostname}", "utf-8"))   

客户:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = input("Enter IP to connect to:\n")
port = int(input("Enter Port to connect to:\n"))
print(f"Connecting to server {ip} ...")
s.connect((ip, port))

msg = s.recv(1024)
print(msg.decode("utf-8"))

在我的本地机器上:在我的 server.py 中打开 20000,它告诉我主机是 127.0.1.1,然后我在我的客户端脚本中输入 127.0.1.1 和 20000,它们就连接了。所以Socket已经和127.0.1.1绑定了。 (附带问题:这个 IP 地址是什么,它类似于我 PC 中进程的内部 IP 地址吗?如果在我的另一台机器上运行 ip a,它是 2 中显示的第一个)

在我的机器上使用 Virtmanager 并运行一台 Linux 服务器(仅命令行)和一台普通的 Ubuntu,服务器再次告诉我主机是 127.0.1.1,我不需要进入其他 VM 即可知道它不起作用,但是起作用的是通过ip a获取服务器的IP地址,在本例中为192.168.122.37,当我将此IP地址输入客户端时,它会连接。但是在这里的套接字中,我再次绑定了 127.0.1.1,所以我放在这里是任意的吗?我应该在这里绑定什么,公众、怪人还是 192. 地址?

我无法开始工作的第一件事是使用 2 个物理设备。在我的 Linux 机器上打开服务器时,我根本无法连接到我的 windows 机器,无论我使用我的公共 IP 地址、我的 127. 还是我的 192. IP 地址。现在我的最终目标是在互联网上做这件事,所以我自己走,在这里描述我为尝试到达我想去的地方所采取的步骤,但在这里我碰到了一堵砖墙,我不知道哪里出了问题。我在服务器上绑定了错误的地址,是我的路由器有问题,还有其他问题吗?

我还尝试使用我的朋友电脑离开我的网络几个国家,但这也只会导致超时(我的理论是他试图打开的路由器端口已关闭,我现在知道如何制作路由器将数据发送到他的PC,这应该不是不可能的,因为firefox和每个使用互联网的应用程序都不需要我手动转发每个端口,我只是不知道如何)。这是我的最终目标,在我的朋友 PC 和我的 PC 之间建立连接,这就是我能走多远(如果本地网络与解决全局连接问题无关,我不介意跳过本地网络),所以,tl;博士:我做错了什么,我需要绑定什么,我需要做什么才能使最终结果起作用?

【问题讨论】:

    标签: python linux sockets tcp network-programming


    【解决方案1】:

    有很多问题要回答。

    地址 127.X.X.X 是为环回接口保留的,最常见的是 127.0.0.1。 loopback 是一个虚拟的但很重要的接口,正如您可能已经猜到的那样,它只能在本地机器上使用。 不能使用 127.X.X.X 地址使两台主机相互通信。


    地址 192.168.X.X(以及 10.X.X.X 和 172.16-31.X.X.)为本地 LAN 保留。它们在 Internet 上无效。

    您不能使用这些地址使两台主机通过公共 Internet 相互通信(除非您创建隧道,这是一个高级网络主题)

    几乎每个人都使用它们,因为我们很久以前就用完了 IPv4 地址,它们很难获得,价格昂贵等。而且这些主机与 Internet 隔离,只能通过转换地址的路由器访问它们。这种路由器功能称为 NAT。典型的路由器有一个有效的 Internet 地址,所有到 Internet 的连接都显示为来自路由器。 如果您从 PC 中获取 jsonip.com 之类的服务,您将获得路由器的地址,而不是 PC 的地址。

    另请参阅:Finding local IP addresses using Python's stdlib


    要使您的程序正常工作,请使其接受所有接口上的连接。请参阅socket docs 中的第一个示例。在 Linux 上,使用 >= 1024 的端口号。


    最后一点是防火墙可能会阻止连接到您的服务器。这取决于您的系统和设置。

    【讨论】:

    • 谢谢!还有几点我很困惑:但是我需要我的路由器 IP 地址才能连接到我朋友的 PC,我该如何创建到他的 PC 的连接?特别是在绑定功能中,我需要放什么IP地址?我知道 192. 是本地的,我不知道为什么我无法连接到我的另一台电脑,我也不知道如何连接到我朋友的电脑。我从来不需要更改我的防火墙以允许 Spotify 工作,所以必须有一种手动的方法,对吧?
    • 在一个典型的设置中(当然,我不知道它是否适用于你的情况),你可以连接到你朋友的路由器,他必须使用端口转发功能来传递流量到他的 PC 的内部 LAN。但是获取朋友的IP地址的事件很棘手,它可能会不时改变(动态DNS可能会有所帮助)。学习网络需要一些时间和精力......
    • 我明白了,我想我需要阅读一下。有什么可以推荐的吗?
    • 我很久以前就学会了网络。不知道现代书籍,但是这本经典仍然被许多人强烈推荐:TCP/IP Illustrated vol。 1 W.R. Stevens,第 2 版.
    猜你喜欢
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 2016-11-19
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    相关资源
    最近更新 更多