#python #內(nèi)網(wǎng)穿透 #端口映射 #port forwarding #socket #nat #TCP/IP #網(wǎng)絡(luò)編程
目的是利用python3的socket庫(kù),建立以下兩個(gè)終端之間的連接并傳輸簡(jiǎn)單的binary數(shù)據(jù):
〇、設(shè)備簡(jiǎn)介
服務(wù)器:
設(shè)備:Windows 10 PC
終端:cmd
網(wǎng)絡(luò):公網(wǎng)動(dòng)態(tài)IP(由無(wú)線路由器接入)
客戶端:
設(shè)備:Android Phone
終端:QPython3 - 終端
網(wǎng)絡(luò):移動(dòng)4G
一、ngrok的配置:
- 點(diǎn)擊這個(gè)鏈接-> ngrok - secure introspectable tunnels to localhost
找到對(duì)應(yīng)的版本,下載并注冊(cè) - 將
ngrok.exe
文件解壓到喜歡的位置 - 將
ngrok.exe
所在的目錄添加到Windows的環(huán)境變量里(Cortana搜索 “env” -> 編輯賬戶的環(huán)境變量 -> path -> 新建) - 點(diǎn)擊這個(gè)鏈接-> ngrok auth
復(fù)制你的Authtoken - [cmd]
ngrok authtoken [你的Authtoken]
二遂庄、執(zhí)行服務(wù)器的代碼:
import socket
import threading
import time
# 源代碼來(lái)自廖雪峰的python3教程
# https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432004374523e495f640612f4b08975398796939ec3c000#0
# 以下是每次TCP連接將要執(zhí)行的線程
def tcplink(sock, addr):
print('Accept new connection from %s:%s...' % addr)
sock.send(b'Greating from Windows 10 PC server!')
while True:
data = sock.recv(1024) # For this session, pause here, once client socket send message proceed following:
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
sock.close()
print('Connection from %s:%s closed.' % addr)
if __name__ == '__main__':
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 監(jiān)聽(tīng)Localhost端口
s.bind(('127.0.0.1', 9999))
s.listen(5)
print('Waiting for connection...')
while True:
sock, addr = s.accept() # Paused here, once received connection proceed the following:
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
三、使用ngrok開(kāi)啟服務(wù)器的TCP端口轉(zhuǎn)發(fā)
- [cmd]
ngrok tcp 9999
后邊的數(shù)字與第二步服務(wù)器端代碼中的端口號(hào)相同即可 -
在ngrok的運(yùn)行信息里找到轉(zhuǎn)發(fā)的公網(wǎng)地址和端口:如下圖紅線部分
四、執(zhí)行客戶端的代碼
在安卓 QPython3* 中打開(kāi)終端田弥,并執(zhí)行以下代碼
將ip
和port
變量修改成第三步中ngrok提示的地址與端口
* QPython3 下載地址
import socket
import androidhelper
droid = androidhelper.Android() # 處理彈出提示
ip = "0.tcp.ngrok.io"
port = 19240
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
datarecv = s.recv(1024).decode('utf-8')
droid.makeToast(datarecv) # 手機(jī)端將彈出
# 發(fā)送數(shù)據(jù)
s.send(b'Steve')
# 接收數(shù)據(jù)
datarecv = s.recv(1024).decode('utf-8')
# 展示數(shù)據(jù)
droid.makeToast(datarecv)