TCP プロキシ データ送信の不確実性を解決する方法
クライアントとサーバーの間でリクエストと応答を転送する TCP プロキシを設計する場合、データが正しく送信されることを確認することが重要です。重要な課題は、クライアントに転送するために必要なすべての情報をサーバーから受信したかどうかを判断するときに発生します。
一般的なアプローチの 1 つは、サーバー接続からの読み取り操作がゼロを返す場合、それはデータ送信の終了。ただし、サーバーが一度に 1 バイトずつソケットにデータを書き込んでいると、プロキシはすべてのデータを受信したと誤って判断する可能性があります。これは、読み取り操作が急速に実行され、サーバーが送信を完了する前に部分的なデータのみを読み取る可能性があるためです。
問題への対処
この問題を解決するには、より堅牢なアプローチは、バッファリングとタイマーを使用することです。データをバッファに読み取り、その長さを定期的にチェックすることで、プロキシは完全な応答をいつ受信したかを判断できます。タイマーにより、サーバーが停止または切断された場合にプロキシが無期限に待機することがなくなります。
さらに考慮すべき点は、ネットワークが分断される可能性があることです。サーバーが一時的に利用できなくなった場合、プロキシはすべてのデータを受信したと想定すべきではありません。代わりに、接続の安定性を維持するためにタイムアウト例外を適切に処理する必要があります。
コードの最適化
質問で提供されているコードは、それぞれに個別の goroutine を使用することで最適化できます。データ転送の方向。これにより、プロキシはクライアント接続とサーバー接続の両方でデータを並行して処理できるようになります。
実装例
次のコード スニペットは、ゴルーチンを使用した最適化されたプロキシ実装を示しています。
package main import ( "fmt" "net" ) type Proxy struct { ServerConn *net.TCPConn ClientConn *net.TCPConn } func (p *Proxy) Proxy() { fmt.Println("Running proxy...") go func() { _, err := io.Copy(p.ServerConn, p.ClientConn) if err != nil { fmt.Println(err) } }() go func() { _, err := io.Copy(p.ClientConn, p.ServerConn) if err != nil { fmt.Println(err) } }() } func main() { // Initialize the TCP connections serverConn, clientConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8080}) if err != nil { fmt.Println(err) return } proxy := Proxy{serverConn, clientConn} proxy.Proxy() }
このコードは、元のコードよりも効率が高く、エラーをより適切に処理します。コード。
以上がTCP プロキシで完全なデータ送信を保証するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。