繁体   English   中英

如何通过互联网(而非本地)使用Python 3套接字客户端/服务器设置?

[英]How to use a Python 3 socket client/server setup over the internet (not locally)?

我正在尝试实现一个简单的聊天程序,该程序使用套接字通过UDP连接传输数据。 但是,我不知道如何正确设置它,以便如果我将其托管在笔记本电脑上,则来自本地网络外部的人都可以访问它。 我正在使用端口5000,并已将路由器上的该端口端口转发给笔记本电脑。 港口转送似乎不是问题。 至少来自portforward.com的“端口转发网络实用程序”似乎检测到它已正确转发。 也许我混淆了需要托管和连接的IP地址? 有问题的代码如下:

import socket
import threading
import sys


class Server:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connections = []

    def __init__(self):
        self.sock.bind(('192.168.1.5', 5000))
        self.sock.listen(1)

    def handler(self, c, a):
        while True:
            data = c.recv(1024)
            for connection in self.connections:
                print(data.decode())
                connection.send(data)
            if not data:
                break

    def run(self):
        while True:
            c, a = self.sock.accept()
            cThread = threading.Thread(target=self.handler, args=(c, a))
            cThread.daemon = True
            cThread.start()
            self.connections.append(c)
            print(self.connections)


class Client:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    usr_name = ""

    def sendMsg(self):
        while True:
            self.sock.send(bytes(self.usr_name + ": " + input("-> "), 'utf-8'))

    def __init__(self, address):
        self.sock.connect((address, 5000))
        self.usr_name = input("Enter a username: ")
        iThread = threading.Thread(target=self.sendMsg)
        iThread.daemon = True
        iThread.start()

        while True:
            data = self.sock.recv(1024)
            if not data:
                break
            print(data.decode())


if len(sys.argv) > 1:
    client = Client(sys.argv[1])
else:
    server = Server()
    server.run()

如您所见,我输入了当前的本地IP地址来托管服务器,而客户端则请求一个IP地址来连接。 我不确定现在该如何在Internet上托管它,但是我尝试了所有我能想到的IP组合,并且它返回了许多错误。

提前致谢。

编辑:我得到的两个主要错误是:

  • 超时错误[WinError 10060]
    • 尝试从其他网络连接时,我的朋友收到了此消息
  • [WinError 10061]
    • 当尝试从同一台计算机使用我的公共IP进行连接时,我会收到此消息

很抱歉,我无法更详细地说明我的错误并提供完整的打印输出,如果能够复制它们,我将尝试对其进行更新。

编辑: 我能够重写它并使它工作,我不再需要任何帮助。 谢谢。

您正在将UDP端口5000转发到5000。

但是您打开的是TCP流,而不是UDP。 这就是SOCK_STREAM意思。 如果要UDP,则需要使用SOCK_DGRAM

因此,您需要使这两个保持一致。 唯一的问题是,我不确定在这里实际要哪个。

一方面,您的代码正在执行面向连接的recv ,并且似乎假定可靠的传输,这意味着您可能需要TCP。

另一方面,您的代码似乎假设每个recv(1024)都会从另一端获取一个准确的send ,这仅适用于UDP。 TCP套接字是字节流,而不是消息流 当执行recv(1024) ,您可以轻松地获得80字节行的前12个字节,这意味着它可以以UTF-8字符的中间结尾,这意味着decode将引发异常。

我认为您要使用TCP,但要在其上面加上成帧协议。 在这里可能有意义的最简单的协议是文本行。 如果您要为每个连接分配一个线程,那么这很容易自己完成,但是使用socket.makefile甚至更容易完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM