3

シナリオは非常に単純です。

TCP/IP を使用して、私 (サーバー) に接続するクライアントがあります。ソケットから送信されたデータを、開いた別のソケットに転送し、そのソケットから受信したデータを逆方向に転送したいと考えています。プロキシのように。

現在、着信接続をリッスンし、クライアントからの接続が確立されたときに別の 2 を生成するスレッドが 1 つあります。スレッドで通信するためのメカニズムを使用する必要があります。

TCP/IP プロキシとして機能するために使用できる簡単なものはありますか? Linux にはソケット転送または何らかのメカニズムがありますか?

4

4 に答える 4

16

iptables を使用してポート転送を行うことができます。これは AC ソリューションではありませんが、パフォーマンスが高く、デバッグが最小限の2 ラインです。

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

最初の行は 192.168.1.50 のポート 80 からポート 80 に転送し、2 番目の行は接続を受け入れ、iptables がドロップしないようにします。

-s 10.0.3.0/24ソースが10.0.3.0から10.0.3.255のすべてのアドレスをキャッチするなど、他のiptablesフラグを使用して追加の制約を追加できます

于 2013-06-20T12:49:38.587 に答える
12

1 つのユーザー レベルのソリューションは、を使用してsocatいます。たとえば、ポート 8080 で接続を受け入れ、それらを 192.168.1.50:9090 に転送するには、次を使用できます。

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

このforkオプションはsocat、複数の接続を許可します。

于 2013-06-20T12:56:49.543 に答える
3

スレッドは必要ありません。またはを見てselect()、スレッドなしで複数のソケットを管理します (Windows を使用している場合は です)。epoll()kqueue()completion port

これは選択ベースのサーバーの例であり、良いスタートになります。

于 2013-06-20T12:44:49.707 に答える
2

単純なソケット転送の場合は、カーネルに任せてください。iptables、またはフロントエンドの 1 つを使用して構成します。

実世界で使用するために複雑なデータ スニッフィング/マングリング/転送が必要な場合は、iptables モジュールを記述します。

データ ストリームをティー (複製/分割) する必要がある場合、またはデータを検査または変更する必要がある場合は、読み進めてください。

Linux 2.6.17 以降と glibc 2.5 以降では、いくつかの優れた機能が提供されていsplice()ますtee()これらを使用して、ペイロードがユーザー空間との間でコピーされるのを回避し、カーネルに特定の量のバイトをある記述子から別の記述子に転送するように指示できます。(tee()データを消費しないため、データの 1 つ以上のコピーを他の記述子に送信できます。)

接続ごとに 2 つのスレッド (方向ごとに 1 つ) を使用し、必要に応じて各スレッドにデータ ストリームの検査/マングル/ティーを読み取らせることができます。1 つの発信ソケットに転送するN 個の着信バイトがあることがわかっている場合は、 を使用しますsplice()。複数の発信ソケットがある場合はtee()、一度に小さなチャンクで非ブロッキング発信ソケットを使用splice()します (ただし、各チャンクの最後の発信ソケットには使用します)。

スレッドは、受信データの一部またはすべてを読み取って、それをどう処理するかを決定できますが、 or を使用する前に、送信する必要があるか、write()またはsend()既に読み取った部分を送信する必要があることに注意してください。既に消費されたデータを魔法のように取得することはありません。splice()tee()

于 2013-06-20T15:49:53.000 に答える