簡體   English   中英

Linux中的簡單套接字轉發

[英]Simple socket forwarding in linux

場景非常簡單:

使用TCP / IP我有一個客戶端連接到我(服務器)我想轉發套接字發送給我的數據到我打開的另一個套接字和我從該套接字向后收到的數據。就像一個代理。

現在我有1個線程,一個人從傳入連接中偵聽,並在建立客戶端連接時產生另一個2。 我必須使用一種機制在線程中進行通信。

有什么更簡單的我可以用來充當TCP / IP代理嗎? Linux有套接字轉發還是某種機制?

您可以使用iptables進行端口轉發 它不是交流解決方案,但它是一個具有良好性能且調試次數最少的2行

從第二個鏈接:

iptables -A PREROUTING -t nat -i eth1 -p tcp \
         --dport 80 -j DNAT --to 192.168.1.50:80

iptables -A INPUT -p tcp -m state --state NEW \
         --dport 80 -i eth1 -j ACCEPT

第一行從端口80前進到端口80,在192.168.1.50上,第二行接受連接,保持iptables不丟棄它。

您可以使用其他iptables標志添加其他約束,例如-s 10.0.3.0/24將捕獲源為10.0.3.0到10.0.3.255的所有地址

一個用戶級解決方案是使用socat 例如,要接受端口8080上的連接並將它們轉發到192.168.1.50:9090,您可以使用:

socat TCP-LISTEN:8080,fork TCP:192.168.1.50:9090

fork選項使socat允許多個連接。

你不需要線程。 看看select()epoll()kqueue() ,以便在沒有任何線程的情況下管理多個套接字(如果你在Windows上,它就是completion port )。

這是基於選擇的服務器的一個例子 ,它將是一個良好的開端。

對於簡單的套接字轉發,讓內核去做。 使用iptables或其中一個前端來配置它。

如果您需要復雜的數據嗅探/修改/轉發以供實際使用,請編寫iptables模塊。

如果您需要T恤(復制/拆分)數據流,或檢查或修改數據,請繼續閱讀。

Linux 2.6.17及更高版本,使用glibc 2.5及更高版本,確實提供了一些不錯的功能: splice()tee() 您可以使用這些來避免有效負載復制到用戶空間和從用戶空間復制,告訴內核將特定數量的字節從一個描述符傳輸到另一個描述符。 tee()不使用數據,允許您將一個或多個數據副本發送到其他描述符。)

您可以在每個連接中使用兩個線程(每個方向一個),並讓每個線程根據需要讀取inspect / mangle / tee數據流。 當您知道有N個傳入字節轉發到一個傳出套接字時,請使用splice() 如果您有多個傳出套接字,請一次使用非阻塞傳出套接字, tee()小塊(但對每個塊的最后一個傳出套接字使用splice() )。

您的線程可以讀取部分/全部傳入數據以決定如何處理它,但請記住,在使用splice()tee()之前,您需要write()send()已讀取的需要send()的部分。 tee() ; 他們並沒有神奇地獲取已經消耗的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM