当前位置: 首页 > 知识库问答 >
问题:

使用公共IP通过Internet操作服务器的问题。Socket和Python3

阎卓
2023-03-14

我正在学习在Python3中使用套接字。我正在开发一个工作如下的小聊天。

    null

问题出现时,通过一个非IP或我自己的IP发布,我试图使它工作。

客户端连接到服务器,我可以发送第一条消息,所有客户端都接收到。但当我从任何客户端发送更多消息时,什么也没有发生,但客户端和服务器之间的连接仍然活跃。我没有错误消息。

我在这次磋商之前所做的行动。

    null
import socket
import threading

class ClaseCliente():

    def __init__(self):

        # Configuramos el tipo de conexion y nos conectamos al servidor.
        self.cliente = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.cliente.connect(('publicIP', 1337))

        self.nick = input("Selecciona tu nombre de usuario: ")

        # Ponemos un thread a recibir los mensajes.
        mensajeRecibido = threading.Thread(target=self.RecibirMensajes)
        mensajeRecibido.daemon = True
        mensajeRecibido.start()

        # Bucle que mantiene vivo el bucle y ademas nos permite enviar mensajes.
        while True:
            mensaje = input()
            try:
                if mensaje != "salir":
                    self.EnviarMensajes(mensaje)
                else:
                    self.cliente.close()
            except:
                self.cliente.close()


    def RecibirMensajes(self):

        while True: # Bucle que mantiene viva la recepcion de mensajes.
            try:
                mensaje = self.cliente.recv(2048)
                print(mensaje.decode()) # Por defecto el encode es "utf-8".
            except:
                pass


    def EnviarMensajes(self, mensaje):

        mensaje = self.nick + "- " + mensaje # Agregamos el nick al mensaje. 
        self.cliente.send(bytes(mensaje.encode())) # Enviamos el mensaje codificado al servidor. Por defecto, en "utf-8".

# --------------------------------------------------------------#


start = ClaseCliente()      
import socket
import threading

class ClaseServidor(): 

    def __init__(self):

        # Configuramos el tipo de conexion y nos ponemos a escuchar 
        self.servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.servidor.bind(('0.0.0.0', 1337))
        self.servidor.listen()
        self.servidor.setblocking(False) # No bloqueamos la conexion (Genera una excepcion si no puede mandar o recibir datos).

        # Ponemos un thread a aceptar las conexiones.
        aceptarConex = threading.Thread(target=self.AceptarConexiones)
        aceptarConex.daemon = True
        aceptarConex.start()

        # Ponemos un thread a leer y reenviar los mensajes entrantes.
        manejoMensajes = threading.Thread(target=self.ManejarMensajesEntrantes)
        manejoMensajes.daemon = True
        manejoMensajes.start()


        # Bucle que mantiene vivo el servidor.
        try:
            while True: 
                Mensaje = input(" =>  ")
                if Mensaje == "salir":
                    self.servidor.close()
                    break
        except:
            self.servidor.close()


    def MandarMensajes(self, mensaje, emisor):

        for receptor in self.listaConexiones:   
            try: 
                # Si la persona que envia el mensaje no es el que lo recibe, envia el mensaje.
                if emisor != receptor:
                    receptor.send(mensaje)
            except:
                # Entramos en la excepcion si no se puede enviar el mensaje a alguien, y lo quitamos de la lista de clientes.
                self.listaConexiones.remove(cliente)


    def AceptarConexiones(self):

        self.listaConexiones = [] # Lista para guardar las conexiones

        while True: # Bucle que mantiene escuchando 
            try:
                clienteConexion, clienteIP = self.servidor.accept() # Empezamos a aceptar conexiones 
                clienteConexion.setblocking(False)
                self.listaConexiones.append(clienteConexion) # Agregamos el objeto cliente a nuestra lista.
                print("se ha conectado el cliente: ", clienteIP[0])
            except:
                pass # Esto es para el setblocking, si se puede aceptar, da una excepcion.


    def ManejarMensajesEntrantes(self):

        while True: # Bucle que mantiene vivo el manejo de mensajes.
            if len(self.listaConexiones) != 0: 
                for cliente in self.listaConexiones: 
                    try:
                        mensaje = cliente.recv(2048) # Recibimos un mensaje.
                        self.MandarMensajes(mensaje, cliente) # Lo mandamos a enviar.
                    except:
                        pass # Esto es para el setblocking, si no recibe un mensaje, da una excepcion.

# --------------------------------------------------------------#

start = ClaseServidor()

共有1个答案

沙靖琪
2023-03-14

代码是正确的,网络配置也是正确的。问题来自我的ISP,它没有分配给我一个公共IP,而是分配给他们一个私有IP。那个拥有公共IP的网络。他们提供了一个很高的价格,有一个真正的公共IP,所以解决方案是雇用一个VPS,并挂载服务器与我在问题中指出的完全相同的配置。

问题的解决方法:询问您的ISP是否有问题在您的家中有一个私人服务器,如果它存在,雇用一个VPS。

 类似资料:
  • 据我所知,我的服务器运行正常,因为我(仅在我自己的计算机上)可以连接到服务器。 当我试图让任何其他计算机连接到它,它从来没有连接,我感到茫然和需要想法。 我使用谷歌chrome连接,就像我之前说的,它工作很好,但只在我的电脑上

  • 我正在aws中运行openshift 我有一个主节点和两个节点。如何向aws公共IP公开服务?我可以在内部访问服务: 我怎么把它暴露给公共IP呢?是否可以在openshfit web控制台中完成?我尝试使用https://docs.openshift.com/container-platform/3.4/dev_guide/expose_service/expose_internal_ip_ser

  • 我一直在遵循这个例子 使用jQuery创建和使用WCF Restful服务 我收到以下错误: XMLHttp请求无法加载http://localhost:48839/EmployeeService.svc/GetEmployeeDetails/.对预检请求的响应未通过权限改造检查:请求的资源上不存在“访问控制允许起源”标头。因此不允许访问起源“http://localhost:57402”。响应具

  • 我正在使用NodeJS和Express。js来运行我的项目。在本地应用程序预览模式下,一切正常。但每次预览时提供的丑陋、长且临时的预览链接并不适合我,我希望有人能够通过以下方式访问我的服务器: 我在这里遵循了指南: AWS Cloud9应用程序预览指南 并将弹性IP分配并关联到运行Cloud9 IDE的EC2实例,我将入站安全规则设置如下: 运行Cloud9 IDE的EC2实例的安全组的入站规则

  • 无法通过公共IP访问EC2 Ubuntu 18.04服务器 重启工作EC2实例 正常重启,没有错误 安全组,检查80,443的入站OK 我还能查什么?

  • 我用django和weasyprint制作了一个应用程序,打印一个带有图片和css文件的pdf文件,设计了我的pdf文件。我使用nginx、gunicorn和supervisor来部署我的应用程序。在我的内部网一切都还好。当我使用INTERNET公共IP地址在INTERNET上发布时,我的pdf文件不再显示图片和css设计。但是所有应用程序的静态文件都工作得很好,我看到了我的gunicorn日志,