@Jagorm

Как создать соединение через интернет, а не через имитатор локальной сети?

Имеется программа, создающая p2p-чат. Программа превосходно работает на одном пк, позволяя чатиться с самим собой. Но при попытке подключения к другому пк вызывается следующее исключение:

TimeoutError: [WinError 10060] Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера

Решить проблему помогает имитатор локальной сети Radmin VPN, если подключаться по ip, предоставляемым этим приложением, но я хочу избавиться от этой обязательной зависимости.

Код:
import socket
import sys
import threading
import time

port = 9091

data = None


def server():
    global data
    global port
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((socket.gethostbyname(socket.gethostname()), port))
    print("Server started your ip", socket.gethostbyname(socket.gethostname()))
    sock.listen(1)
    conn, addr = sock.accept()

    while True:
        data = conn.recv(1024)
        if data.decode('utf-8') == 'stop':
            print(f'Anybody>>> {data.decode("utf-8")}')
            sock.close()
            return None
        else:
            print(f'Anybody>>> {data.decode("utf-8")}')
        conn.send(f'Server {data.decode("utf-8")}'.encode("utf-8"))


def client():
    global data
    time.sleep(0.1)
    sock = socket.socket()
    while True:  # Получение ip для подключения
        ip = input('ip to connect>>> ')
        try:
            sock.connect((ip, port))
            break
        except:
            print('invalid ip or connect error')

    while True:  # Процесс отправки сообщений
        message = input('You>>> ')
        if message == 'stop':
            sock.send(message.encode("utf-8"))
            sock.close()
            return None
        else:
            sock.send(message.encode("utf-8"))
        data = sock.recv(1024)


p1 = threading.Thread(target=server, name="t1")
p2 = threading.Thread(target=client, name="t2")

p1.start()
p2.start()


Заранее благодарен
  • Вопрос задан
  • 75 просмотров
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
В базовом случае у сервера должен быть внешний IP и открыт соответствующий порт.
Если сервер за подконтрольным NAT (например, роутером), то порт должен быть проброшен через NAT.
Если сервер за провайдерским NAT (который пользователю неподконтролен), то тут уже сложнее. Есть техники NAT traversal, но они не вполне тривиальны и обычно требуют наличия вспомогательного узла с внешним IP.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы