如何在两台电脑之间用Python创建TCP连接



到目前为止,我已经制作了一个非常基本的客户端/服务器应用程序,用于创建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.0.1.1,然后我在我的客户端脚本和20000中输入127.0.0.1,然后它们连接。因此,Socket已与127.0.0.1.1绑定。(附带问题:这个IP地址是什么,它像我电脑中进程的内部IP地址吗?如果在我的另一台机器上运行ip a,它是2的第一个(

在我的机器上使用Virtmanager,运行一个Linux服务器(仅限命令行(和一个普通的Ubuntu,服务器告诉我主机是127.0.0.1,我不需要输入到另一个虚拟机中就知道它不会工作,但有效的是通过ip a获取服务器的IP地址,在本例中为192.168.122.37,当我将该IP地址输入到客户端时,它连接起来。但在这里的套接字中,我再次绑定127.0.0.1.1,所以我放在这里的内容是任意的吗?我应该在这里绑定什么,公众,怪异还是192。住址

我不能上班的第一件事是使用两个物理设备。在我的Linux机器上打开服务器时,我根本无法连接到我的windows机器,无论我是否使用我的公用127。或者我的192。IP地址。现在我的最终目标是在互联网上做这件事,所以我走上前去,在这里描述我为达到我想要的目标而采取的步骤,但在这里我遇到了一堵砖墙,我不知道哪里出了问题。我在服务器上绑定了错误的地址吗?我的路由器有问题吗?还有其他问题吗?

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

有很多问题需要回答。

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


地址192.168.X.X(以及10.X.X.X和172.16-31.X.X(保留给本地LAN。它们在互联网上无效。

您不能使用这些地址使两个主机在公共互联网上相互通信(除非您创建了一个隧道,一个高级网络主题(

几乎每个人都使用它们,因为我们很久以前就用完了IPv4地址,它们很难获得,价格昂贵,等等。而且这些主机与互联网隔离,只能通过翻译地址的路由器才能访问。这种路由器功能被称为NAT。一个典型的路由器有一个有效的互联网地址,所有到互联网的连接都来自路由器如果你从电脑上获得像jsonip.com这样的服务,你会得到路由器的地址,而不是电脑的地址

另请参阅:使用Python查找本地IP地址';s stdlib


要使程序正常工作,请使其接受所有接口上的连接。请参阅socket文档中的第一个示例。在Linux上,使用端口号>=1024个端口<1024是保留的,常规用户不可用。


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

最新更新