0

我正在尝试使用 Ngrok 使用该socket模块连接两个 python 脚本。我试过用 ngrok.exe 和 pyngrok 来做这件事。尝试使用portas1234580(其他一切都超时)与客户端连接。

在客户端s.connect((ip, port))没有错误,但是 Python server.py 和 ngrok 终端没有注册任何东西。502 bad gateway当我将 URL 放入 Web 浏览器时,该 URL 肯定可以作为 Ngrok 注册的。

我认为这是因为套接字没有使用 HTTP,而是使用 TCP,但是当我使用 TCP 标志 ( ngrok.exe TCP 12345) 启动 Ngrok 时,转发地址看起来像tcp://0.tcp.ngrok.io:xxxxx我将其放入客户端 socket.connect()时返回的地址socket.gaierror: [Errno 11001] getaddrinfo failed

所以我想我的问题是,如何让 Python 客户端套接字接受这个地址,还是我应该做一些不同的事情?

谢谢

服务器.py

from pyngrok import ngrok
import socket

port = 12345

s = socket.socket()
s.bind(('', port))

public_url = ngrok.connect(port)
print("ngrok tunnel \"{}\" -> \"http://127.0.0.1:{}/\"".format(public_url, port))

s.listen(5)      
print("socket is listening" )

c, addr = s.accept()

print('Got connection from', addr )

c.send(str.encode(str("Yes")))

while True:
    c.recv(1024).decode("utf-8")

客户端.py

import socket
s = socket.socket()
url = "copied from server or ngrok"
ip = socket.gethostbyname(url)
port = 12345
s.connect((ip, 12345))
4

2 回答 2

1

我是 的开发人员pyngrok,我看到您正在使用它。文档中实际上有一个 TCP 套接字/客户端集成示例,可以在这里找到。

但你在正确的轨道上。简而言之,您没有指定协议,这意味着http正在使用默认协议 ( )。你需要告诉pyngrok并且ngrok你想建立一个tcp隧道。所以改为这样做:

ngrok_tunnel = ngrok.connect(port, "tcp", remote_addr="{}:{}".format(host, port))
print("ngrok tunnel \"{}\" -> \"tcp://127.0.0.1:{}/\"".format(ngrok_tunnel.public_url, port))

对于hostand port,您需要首先设置一个ngrok子域(您可以在此处执行此操作),例如host="1.tcp.ngrok.io". 然后你也将同一个主机/帖子传递给你client.py(你做错的地方包括协议tcp://,不要管它)。

于 2020-05-17T14:54:39.813 回答
0

另一个使用 ngrok 的安全 Python 套接字示例。您可以设计代码忽略 ngrok,然后在测试后注入 pyngrok 依赖项(几行)。

ssl_client.py

# -*- coding: latin-1 -*-

from OpenSSL import SSL
import sys, os, select, socket

def verify_cb(conn, cert, errnum, depth, ok):
    # This obviously has to be updated
    print ('Got certificate: %s' % cert.get_subject())
    return ok

if len(sys.argv) < 3:
    print ('Usage: python[2] client.py HOST PORT')
    sys.exit(1)

dir = os.path.dirname(sys.argv[0])
if dir == '':
    dir = os.curdir

# Initialize context
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.set_verify(SSL.VERIFY_PEER, verify_cb) # Demand a certificate
ctx.use_privatekey_file (os.path.join(dir, 'simple','client.pkey'))
ctx.use_certificate_file(os.path.join(dir, 'simple','client.cert'))
ctx.load_verify_locations(os.path.join(dir, 'simple','CA.cert'))

# Set up client
sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sock.connect((sys.argv[1], int(sys.argv[2])))

while 1:

    line = sys.stdin.readline()
    if line == '':
        break
    try:
        sock.send(line.encode())
    except SSL.Error:
        raise
        print ('Connection died unexpectedly')
        break


sock.shutdown()
sock.close()

ssl_server.py



from OpenSSL import SSL
import sys, os, select, socket


def verify_cb(conn, cert, errnum, depth, ok):
    # This obviously has to be updated
    print ('Got certificate: %s' % cert.get_subject())
    return ok

if len(sys.argv) < 2:
    print ('Usage: python[2] server.py PORT')
    sys.exit(1)

dir = os.path.dirname(sys.argv[0])
if dir == '':
    dir = os.curdir

# Initialize context
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.set_options(SSL.OP_NO_SSLv2)
ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) # Demand a certificate
ctx.use_privatekey_file (os.path.join(dir, 'simple', 'server.pkey'))
ctx.use_certificate_file(os.path.join(dir, 'simple', 'server.cert'))
ctx.load_verify_locations(os.path.join(dir, 'simple', 'CA.cert'))

# Set up server
server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
server.bind(('', int(sys.argv[1])))
server.listen(3) 
server.setblocking(0)

clients = {}
writers = {}

def dropClient(cli, errors=None):
    if errors:
        print ('Client %s left unexpectedly:' % (clients[cli],))
        print ('  ', errors)
    else:
        print ('Client %s left politely' % (clients[cli],))
    del clients[cli]
    if cli in writers:
        del writers[cli]
    if not errors:
        cli.shutdown()
    cli.close()
from pyngrok import ngrok

port=6063 #make a param
public_url = ngrok.connect(port, "tcp").public_url
print(f"ngrok tunnel '{public_url}' -> 'tcp://127.0.0.1:{port}'")

while 1:

    try:
        r,w,_ = select.select([server]+list(clients.keys()), writers.keys(), [])
    except:
        
        raise

    for cli in r:
        if cli == server:
            cli,addr = server.accept()
            print ('Connection from %s' % (addr,))
            clients[cli] = addr

        else:
            try:
                ret = cli.recv(1024)
                print(555, ret)
            except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError):
                pass
            except SSL.ZeroReturnError:
                raise
                dropClient(cli)
            except SSL.Error as errors:
                raise
                dropClient(cli, errors)
            else:
                if not cli in writers:
                    writers[cli] = b''
                writers[cli] = writers[cli] + ret
    if 0:
        for cli in w:
            try:
                ret = cli.send(writers[cli])
            except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError):
                pass
            except SSL.ZeroReturnError:
                print(111)
                raise
                dropClient(cli)
            except SSL.Error as  errors:
                raise
                dropClient(cli, errors)
            else:
                writers[cli] = writers[cli][ret:]
                if writers[cli] == '':
                    del writers[cli]

for cli in clients.keys():
    cli.close()
server.close()

第 59 行的 URL 更改

详细信息在这里:secure-python-socket-using-ngrok

于 2021-11-16T16:03:39.670 回答