4

私は自分自身の少し大きなプロジェクトに取り組んでおり、python でローカルホスト プロキシを作成する必要があります。

私が書いた方法は、localhost のポート 8080 に TCP サーバー (ソケットと SOCK_STREAM を使用) があることです。スライシング、string.find() を使用してローカル ホストからの要求を受け入れ、gethostbyname() がそのターゲット IP を見つけるため、別の TCP ソケットを開き、要求を送信し、recv の応答を返します。その後、応答を localhost プロキシに中継し、ローカルホスト プロキシはそれをブラウザに返します。

これは、十分なデバッグ メッセージと、ブラウザーの要求と受信した応答を収集するためのデバッグ ファイルを含むコードです (これは単なるプロトタイプであるため、while 1 ループの代わりに for ループが制限されていることにも注意してください)。

import socket

local = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

f = open('test.txt', 'a')
local.bind(('localhost', 8080))
local.listen(5)
for i in xrange(20):
    print '=====%d=====\n' % i
    out = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    data, addr = local.accept()
    print 'Connection accepted'
    buffer = data.recv(4096)
    print 'data recieved'
    f.write('=============================================================\n')
    f.write(buffer)
    end = buffer.find('\n')

    print buffer
    #print buffer[:end]
    host = buffer[:end].split()[1]
    end = host[7:].find('/')

    print host[7:(end+7)]
    host_ip = socket.gethostbyname(host[7:(end+7)])
    #print 'remote host: ' + host + ' IP: ' + host_ip
    print 'sending buffer to remote host'
    out.connect((host_ip, 80))
    out.sendall(buffer)
    print 'recieving data from remote host'
    reply = out.recv(4096)
    out.close()
    print 'data recieved from remote host'
    f.write('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n')
    f.write(reply)
    f.write('\n\n\n')
    print 'sending data back to local host'
    data.sendall(reply)
    print 'data sent'
local.close()
out.close()    
f.close()

今私の問題は、最初のいくつかのリクエストではうまく機能しているように見え、htmlといくつかの画像を取得しますが、データを取得しないため、ある時点で常に「データ受信」ポイントで停止して終了することです。バッファが空です。ブラウザーはまだページの要素を読み込んでいることを示していますが、ブラウザーが停止してテキスト ログ ファイルを見ると、バッファーが空であることがわかります。つまり、ブラウザーはプロキシに何も送信していないということですか?

問題は、ブラウザがリクエストを送信する方法と、スクリプトがこの動作に適切に反応しないことにあると推測しています。

Twist フレームワークを使用できることはわかっていますが、このようなものを自分で書くことを学びたいと思っています。私は SocketServer について読んでいましたが、それを使用するかもしれませんが、率直に言って、ここで問題の原因がよくわからないため、問題が解決するかどうかはわかりません。私のスクリプトはブラウザーにとって遅すぎますか? サーバーは複数の応答を送信し、受信ソケットはより多くのパケットをリッスンする必要がありますか? バッファー サイズ (4096) が小さすぎますか?

正しい方向へのナッジを本当に感謝します。

ありがとう!

4

1 に答える 1

2

さて、私は自分の質問に答えることができました。私が以前に疑っていたことは、部分的には真実でした - ブラウザは何かを待っていて、何かが返信されたのです。

私は Wire Shark を起動し、いくつかの実験を行ったところ、私のプロキシが多くの醜い TCP RST を Wireshark に表示することに気付きました。また、通常の接続では、多くのサーバー応答がいくつかの異なるパケットに分割されることにも気付きました。

基本的に、out.recv が応答の一部しか取得していなかったため、私のプログラムはサーバーからすべての応答を取得していませんでした。明らかな答えは、ループを作成してすべての応答をリッスンすることでした。http://www.binarytides.com/receive-full-data-with-the-recv-socket-function-in-python/で完璧なソリューションを見つけました。

私はすぐにプログラムを少し書き直しましたが、それは魅力のように機能します。これで、プロジェクト全体を進めることができます。

これが将来、同様の問題を抱えている他の誰かに役立つことを願っています。

于 2012-10-13T15:54:49.950 に答える