【C++】內外網連接原理與ASIO 代理

參考資料:《Boost Asio C++網絡編程》第五章

學會網絡編程之後,理所當然會有這樣的想法:在單位電腦上部署自己寫的服務段軟件,在家裏電腦上部署客戶端,從而遠程辦公。但是實際操作下來可以發現,兩臺電腦上的ip地址,根本不能建立socket直連,這是爲什麼呢。

內外網連接規則

對於普通網絡用戶,電腦入網都分配的是內網IP。儘管IPv6已經出來多年,目前互聯網公網IP普遍還在IPv4階段,可利用的IP地址相當有限。寬帶商本身僅僅能拿到少量IPv4地址的使用權,不會給每個個人用戶配置單獨的公網IP,爲了讓每個用戶上網,把用戶都納入局域網中分配局域網IP;建立網關設備作爲門戶,收集每個用戶的socket請求然後變爲門戶IP的數據包,轉發到公網上去,建立長期連接;用戶連接單獨開啓一個端口用於標識數據轉發地址;但是不允許外網主動申請連接,如圖1
在這裏插入圖片描述

圖1
實際上,用戶每次登錄上網的IP都是動態的;而且轉發數據包所用的端口也是動態的,所以外網根本沒法主動定位內網電腦的地址,顯然,單位和家裏處於不同內網的兩臺電腦,也無法直接連接,全被網關服務器擋住了。
內網穿透

既然內網之間無法連接,內網的網絡用戶,需要其他方式才能進行互聯,實現聊天、傳文件、遠程控制等功能。上述可知,內網能主動連接公網服務器建立長期連接,但不能反向,那麼不同內網用戶可以預先向同一公網服務器建立長期連接,然後公網服務器進行轉發,間接實現內網電腦之間的互聯,如圖2:
在這裏插入圖片描述

圖2
資源利用策略

一般情況下,一臺公網服務器就會佔用一個公網IP,如果服務量巨大,那這臺服務器會崩潰,需要將壓力分散到多個服務器中,一種可用策略如圖3:
在這裏插入圖片描述

圖3
這裏,公網服務器在查看它的內網服務器的負載之後,決定將用戶連接服務交給其中一臺服務器進行處理,這些數據包同樣經過了內網轉發環節。不過這裏還不清楚的是:如果一個IP配備一臺網關服務器,巨大數據流量下,服務器得有多強的數據吞吐量? 實際服務中,爲了有效利用網絡資源,存在至少兩種處理策略: 1. 一套服務器,統一管理所有的用戶連接。該策略管理能力很強,常見的用法就是編寫一個控制頁面,隨時封殺用戶。這種策略在很多用戶連接的情況下,壓力成倍增長。 2. 分散的若干服務器,每臺服務器管理一批用戶進行小範圍互聯。P2P屬於這種類型,對每個服務器的壓力較小,可以輕鬆擴展,但是管理混亂。
ASIO代理服務

代理服務器很簡單,需要配備兩個端口,一個接收客戶端sock連接,一個接收服務端socket連接。端口可以設置reuse屬性,進行多進程監聽,但是最好一個端口僅對應一個服務。

class proxy : public boost::enable_shared_from_this<proxy> {
proxy(ip::tcp::endpoint ep_client, ip::tcp::endpoint ep_serv
er) : ... {}
void on_start() {
	do_read(client_, buff_client_);
	do_read(server_, buff_server_);
}

這裏是異步調用,直接啓動client和server的監聽即可,後續回調函數需要將sock作爲參數,好識別究竟是客戶端還是服務端發出了響應:

void do_read(ip::tcp::socket & sock, char* buff) {
	async_read(sock, buffer(buff, max_msg), MEM_FN3(read_com
plete,ref(sock),_1,_2), MEM_FN3(on_read,ref(sock),_1,_2));
}

注意這裏使用std/boost::ref(),顯示調用std/boost::bind執行引用參數傳遞,因爲bind默認參數列表都是值傳遞。

void on_read(ip::tcp::socket & sock, const error_code& err,
size_t bytes) {
char * buff = &sock == &client_ ? buff_client_ : buff_se
rver_;
do_write(&sock == &client_ ? server_ : client_, buff, by
tes);
}

實際操作很簡單,如果是client的sock讀取進來,那麼就向server的sock寫入同樣的數據;反之亦然。代理的一大作用在這裏,就是可以把client/server傳入的數據進行修改,再用不同的sock傳遞出去。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章