Python 3 在 Internet 上使用套接字

Python 3 Using Sockets over the Internet

我一直在尝试设置可在 Internet 上运行的套接字。我通过堆栈溢出进行了上下搜索,但似乎找不到我需要的答案。

当我 运行 server.py 我收到这个错误:

Traceback (most recent call last):
  File "server.py", line 16, in <module>
    serversocket.bind((host, port))
OSError: [WinError 10049] The requested address is not valid in its context

请注意,以下内容似乎适用于本地 wifi。

服务器代码:

# server.py 
import socket                                      

# create a socket object
serversocket = socket.socket(
            socket.AF_INET, socket.SOCK_STREAM) 


#get ip address
print("You are the server.")
print("What is your ip? If you do not know, look up <my ip> on google.")
host = input(">")                         

port = 0                                          

# bind to the port
serversocket.bind((host, port))                                  

# queue up to 5 requests
serversocket.listen(5)   
clientsocket,addr = serversocket.accept()                                          

def messenger():
    # establish a connection    
    tm = clientsocket.recv(1024)
    tm = tm.decode('ascii')

    if tm == "9+10":
        message = "21"
    elif tm == "sweg":
        message = "swegedy swooty feel the booty"
    else:
        message = "feggeet"
    clientsocket.send(message.encode('ascii'))
    messenger()
messenger()

客户端代码:

# client.py  
import socket

#get ip address
print("You are the client.")
print("What is your servers ip?")
host = input(">")  

# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

port = 0
s.connect((host, port))

# Receive no more than 1024 bytes
def messenger():
    message = input("command:")
    s.send(message.encode("ascii"))
    tm = s.recv(1024)                                     
    print(tm.decode('ascii'))
    messenger()
messenger()

据我了解,只要我插入 public IP 地址,它就应该可以工作。但是,我只收到该错误消息。

我做错了什么?

您的服务器只能绑定到它所在的主机地址。 IIRC,你应该绑定到 0.0.0.0,这绑定到当前机器上的所有地址。然后您可以在本地连接客户端(同一台机器 127.0.0.1,本地机器 - 您需要知道机器的内部 IP 地址)。

修正,常用的方法是serversocket.bind((socket.gethostname(), 80))

如果您想从 Internet 访问它,您需要知道的第一件事是您机器的 Internet 地址。由于您不太可能直接连接到互联网,因此这可能是您路由器的 IP 地址。

下一步将是允许通过路由器将端口转发到您的计算机 - 再一次,关于这个可以写一篇长篇大论。

我的 python 代码也遇到了同样的问题,现在已经解决了!

首先你需要将服务器绑定到本地主机,而不是 public ip 地址:SERVER = socket.gethostbyname(socket.gethostname())

其次,您需要将地址的客户端设置为服务器的public ip,而不是本地ip:SERVER = '<server side public ip address goes here>'

如果这对您不起作用,请不要担心,您需要在路由器中启用端口转发,您可能可以在互联网上找到如何启用!

然后大多数人对此感到厌倦,因为它不会起作用,但在最后一步后会起作用!

如果你使用 windows 这会容易得多,因为我使用 windows 作为我的 OP 我将通过屏幕截图向你展示如何做到这一点:
首先,您需要进入 windows 防火墙设置,然后点击高级设置

在那之后,这应该会弹出!

然后单击入站规则并在右上角单击新建规则!

在那里您可以单击端口并单击下一步,然后 select 您在 python 客户端或服务器 python 文件中使用的端口:

之后单击允许此连接并单击下一步和下一步直到完成,然后对服务器执行此操作并确保对所有客户端计算机也执行此操作!!:

之后,您需要重新设置,但这次应该是针对 UDP 的: 如果你两者都做了,那就试试吧。