【问题标题】:Python Socket communication across networks not working跨网络的Python Socket通信不起作用
【发布时间】:2018-05-26 21:06:09
【问题描述】:

我正在尝试使用 socket 模块在我和我朋友的计算机之间建立通信。我在我的电脑上运行服务器代码,他在他的电脑上运行客户端代码。代码如下:

服务器:

import socket

host = "XXX.XXX.XX.XXX" # IP of my computer
port = 2000

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))

addrs = []

print("Server started")
while True:
    data, addr = s.recvfrom(1024)
    if not addr in addrs:
        addrs.append(addr)
    data = data.decode("utf-8")
    print("Recieved: " + str(data))
    print("Sending: " + data)
    for add in addrs:
        s.sendto(data.encode("utf-8"), add)

客户:

import socket
import time

host = "XXX.XXX.XXX.XXX" # External IP of my router
port = 2001

server = (host, port)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setblocking(False)

while True:
    message = "Test message"
    time.sleep(1)
    print("Sending: " + message)
    s.sendto(message.encode("utf-8"), server)
    try:
        data, addr = s.recvfrom(1024)
    except BlockingIOError:
        pass
    else:
        data = data.decode("utf-8")
        print("Recieved: " + str(data))

注意:客户端与服务器代码中的端口不同,以确保我的端口转发确实在做某事。

我已经在我的路由器上设置了端口转发。当我在我的计算机(甚至另一台与我的 WiFi 连接的计算机)上运行这两个脚本时,一切正常,并且我知道端口转发正在做它的事情。但是,当我的朋友(连接到不同的 WiFi)运行客户端代码时,它不起作用。没有抛出错误,但他发送的数据我的计算机和路由器的端口转发规则都没有收到。

这个问题可能源于我的代码,还是更有可能是因为我的路由器没有正确设置?

【问题讨论】:

  • 也许尝试通过使用socket.SOCK_STREAM而不是socket.SOCK_DGRAM来使用TCP套接字
  • 或者在没有一秒超时的情况下对其进行测试,但在打印之前检查data != b''并注释掉print('Sending ...'),这样你就不会收到很多空消息

标签: python sockets


【解决方案1】:

好的,我在我的 Android 手机上设置了一个热点。在这种情况下,它是您的“路由器”,使用了我手机的 IP 地址。并在计算机上尝试运行您的客户端代码,它在客户端上发送测试消息:

发送:测试消息 发送:测试消息 发送:测试消息 发送:测试消息 ....

但我在您的服务器上没有收到任何信息,仍然说服务器已启动。

所以我像这样在“客户端应用程序”上配置了您的主机变量,您的端口也不一致,服务器上的 2000 和客户端上的 2001:

host = "" # 我的路由器的外部 IP 端口 = 2000 笔记!!我把主机留空了

因为我认为由于某种原因服务器在 PC 上本地托管,所以您正在运行服务器。这样我也可以从运行服务器应用程序的同一台计算机本地连接:

host = "localhost" # 我的路由器的外部 IP

在您的客户端应用程序上。

这就是一切的样子。

服务器代码 在你的通勤者上运行它。

import socket

host = "" # IP of my computer
port = 2000

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))

addrs = []

print("Server started")
while True:
    data, addr = s.recvfrom(1024)
    if not addr in addrs:
        addrs.append(addr)
    data = data.decode("utf-8")
    print("Recieved: " + str(data))
    print("Sending: " + data)
    for add in addrs:
        s.sendto(data.encode("utf-8"), add)

取决于您运行 serverApp 的位置。使用运行服务器的计算机的 IP。我还在学习,所以我不知道如何设置它以使用您的路由器的 IP。

客户端应用代码 在您的朋友计算机或更多计算机上运行它。甚至在安卓上。

import socket
import time

host = "ip_of_the_computer_the_server_is_running_on" # connecting from another computer
#host = "localhost" # If you connecting locally

port = 2000

server = (host, port)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setblocking(False)

while True:
    message = "Test message"
    time.sleep(1)
    print("Sending: " + message)
    s.sendto(message.encode("utf-8"), server)
    try:
        data, addr = s.recvfrom(1024)
    except BlockingIOError:
        pass
    else:
        data = data.decode("utf-8")
        print("Recieved: " + str(data))

您的路由器只能用于同一个 AP 连接。 用我的 TOTO-LINK 测试它工作正常。只要我不在客户端主机上使用路由器的 IP。

演示 服务器

客户

手机客户端

【讨论】:

  • 我不确定我是否理解您的回答。我已经编辑了我的问题,以强调我的朋友与我在不同的 WiFi 上(这是我的实际问题)。那你的答案还适用吗?
  • 好的,我明白了,我认为它不适用。因为如果他们在不同的 WIFI 网络上,我不明白你想如何联网。我没有练习过远程访问。
  • 我也会尝试这样做。这真有趣。我认为启用远程连接还有更重要的功能。
【解决方案2】:

此代码实际上是 100% 正确的,错误是在我的端口转发中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    相关资源
    最近更新 更多