0

I tried using a socket for 2 sends. The first one succeeds and the next one does not. From the http://docs.python.org/howto/sockets.html it would appear that multiple sends should be allowed. For Better or worse, I don't really need to read from the socket. I have used twisted, but for the present purpose, I would like to stick to a socket, if I can help it(partly because I am using it within an application already using twisted to communicate.. this is a seperate connection).

"When the connect completes, the socket s can be used to send in a request for the text of the page. The same socket will read the reply, and then be destroyed. That’s right, destroyed. Client sockets are normally only used for one exchange (or a small set of sequential exchanges)."

return value for the send that succeeds = 35 return value for the send that FAILS = 32

code with some minor editing to remove any business logic.

self._commandSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)


def sendPrereqs(self,id,prereqs):
    self._commandSock.connect(self._commandConnection)
    #parse prereqs
    temp = prereqs.split(',')
    for pair in temp:
        tup = pair.partition(':')
        try:
            command = 'some command'
            logging.info('sending command: ' + command)
            ret = self._commandSock.send(command)
            if ret == None:
                logging.info('send called successfully: ' + command)
            else:
                logging.info('socket returned non-None: ' + str(ret))
        except:

            print 'Unexpected Exception ', sys.exc_info()[0]()
            print sys.exc_info()
            #logging.info('Unexpected Exception '+ str(sys.exc_info()[0]()))
            #logging.info(' ' + str(sys.exc_info()))
    self._commandSock.close()`
4

2 に答える 2

2

成功した送信の戻り値 = 35 失敗した送信の戻り値 = 32

ドキュメントによると、送信が成功すると None が返されるはずです。

いいえ、そうではありません。ドキュメントには次のように記載されています。

送信されたバイト数を返します。アプリケーションは、すべてのデータが送信されたことを確認する責任があります。一部のデータのみが送信された場合、アプリケーションは残りのデータの配信を試行する必要があります。この概念の詳細については、Socket Programming HOWTO を参照してください。

「FAILS」の意味をまだ説明していません。呼び出しは正常に返され、sendほぼ確実に 32 バイトがソケット書き込みバッファーに配置されます。

失敗していると思う唯一の理由が正しい値を返すことである場合、答えは明らかに失敗していないということです。

他の何かが間違っている場合、より高いレベルで間違っている可能性があるあらゆる種類のものが存在します。1 つの可能性は次のとおりです。サーバー (特に、ソケットをよく理解していない人によってコーディングされた場合) はrecv()、35 バイトのいずれか、およびrecv()32 バイトのいずれかを予期するようにコーディングされています。しかし、実際にrecv()は 67 バイトの 1 つを取得し、2 番目のバイトを永遠に待っています。send()ストリーム (TCP) ソケットのそれぞれrecv()が反対側のソケットに対応することを保証するルールはありません。個別のメッセージを区別するある種のストリーム プロトコルを作成する必要があります。

一方、あなたが言及している引用は無関係です。単純な Web ブラウザーでクライアント ソケットがどのように使用されるかを説明しています。接続を確立し、1 回の送信を行い、すべてのデータを受信して​​から、接続を破棄します。それがあなたを誤解させた理由はわかります。改善のためにドキュメントのバグを報告することをお勧めします。しかし、今のところ、それを無視してください。

クライアントが正しいデータを送信していて、問題がサーバーにあることを完全に確認したい場合は、次の 2 つの簡単な方法があります。

  1. 単純な代替サーバーとしてnetcatを使用し (たとえば、 nc -kl 6000「6000」を実際のポートに置き換えます)、サーバーが見ていると思われるものを確実にログに記録します。

  2. Wiresharkを使用して、クライアントとサーバー間の接続を監視します。

問題がサーバー側にあることを確認したら、サーバーをデバッグする必要があります。それについて助けが必要な場合は、クライアントの代わりにサーバーコードを投稿し、クライアントが正しい情報を送信していることを確認して (ここにリンクを付けて) 説明できる新しい質問で行うのがおそらく最善です。

于 2012-10-03T19:49:07.730 に答える
0

ドキュメントは、一般的なシナリオのみを参照しています。ソケットが閉じられていない限り、すべてのソケットsendで 、sendall、およびを何度でも呼び出すことができます。sendto

これらのメソッドは送信されたバイト数を返すことに注意してください。32 と 35 は、最初に 32 バイトを送信し、2 回目に 35 バイトを送信したことを意味します。

が例外なしで返されるという事実はsocket.send、データがオペレーティング システムに渡されたことを意味しますが、実際にエンドポイントに到達した (またはそこでアプリケーションによって正しく読み取られた) ことを意味するわけではありません。

于 2012-10-03T19:20:04.050 に答える