2017-01-07 6 views
1

ソケットを使用してサービスに接続したいとします。私がSocket.Connectを使用すると、応答は200 OKであり、データを正常に受信できますが、Socket.ConnectAsyncを使用すると400の不正な要求が返されます。ここでSocket.ConnectAsyncは、Socket.Connectが200を取得している間に400の不正な要求を受け取ります。

はSocket.Connectのコードです:

SocketAsyncEventArgs myev; 
private void Receive(SocketAsyncEventArgs e) 
{ 
    myev = e; 
    SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop(); 
    readEventArgs.RemoteEndPoint = remote; 
    Socket connectSocket; 
    connectSocket = new Socket(remote.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
    connectSocket.Connect(remote);//Sync Connect 
    ProcessConnect(readEventArgs); 
} 
private void ProcessConnect(SocketAsyncEventArgs e) 
{ 
    AsyncUserToken token = (AsyncUserToken)myev.UserToken; 
    if (myev.BytesTransferred > 0 && myev.SocketError == SocketError.Success) 
    { 
     e.SetBuffer(myev.Offset, myev.BytesTransferred); 
     bool willRaiseEvent = ((AsyncUserToken)e.UserToken).Socket.SendAsync(e); 
     if (!willRaiseEvent) 
     { 
      ProcessServerSend(e); 
     } 
    } 
    else 
    { 
     CloseClientSocket(e); 
    } 
} 

、ここではSocket.ConnectAsyncのコードです:私たちはSocketAsyncEventArgsPool m_readWritePool;としてm_readWritePoolを定義し、1000年でそれを満たしている

SocketAsyncEventArgs myev; 
private void Receive(SocketAsyncEventArgs e) 
{ 
    myev = e; 
    SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop(); 
    readEventArgs.RemoteEndPoint = remote; 
    Socket connectSocket; 
    connectSocket = new Socket(remote.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
    ((AsyncUserToken)readEventArgs.UserToken).Socket = connectSocket; 
    bool willRaiseEvent = connectSocket.ConnectAsync(readEventArgs);//Async Connect 
    if (!willRaiseEvent) 
    { 
     ProcessConnect(readEventArgs); 
    } 

} 
private void ProcessConnect(SocketAsyncEventArgs e) 
{ 
    AsyncUserToken token = (AsyncUserToken)myev.UserToken; 
    if (myev.BytesTransferred > 0 && myev.SocketError == SocketError.Success) 
    { 
     e.SetBuffer(myev.Offset, myev.BytesTransferred); 
     bool willRaiseEvent = ((AsyncUserToken)e.UserToken).Socket.SendAsync(e); 
     if (!willRaiseEvent) 
     { 
      ProcessServerSend(e); 
     } 
    } 
    else 
    { 
     CloseClientSocket(e); 
    } 
} 

注意アイテム。私たちのようにProcessServerSendを定義している

:すべての機能が同じであることを

private void ProcessServerReceive(SocketAsyncEventArgs e) 
{     
    AsyncUserToken token = (AsyncUserToken)myev.UserToken; 
    if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) 
    { 
     myev.SetBuffer(e.Offset, e.BytesTransferred); 
     byte[] buf = new byte[e.BytesTransferred]; 
     for (int i = 0; i < e.BytesTransferred; i++) 
     { 
      buf[i] = e.Buffer[e.Offset + i]; 
     } 
     string message = Encoding.UTF8.GetString(buf); 
     //The message contains '200 ok' or '400 bad request' when using Connect or ConnectAsync respectively. 
     bool willRaiseEvent = token.Socket.SendAsync(myev); 
     if (!willRaiseEvent) 
     { 
      ProcessSend(myev); 
     } 
    } 
    else 
    { 
     CloseServerSocket(e); 
    } 
} 

注しかしconnectメソッド:

private void ProcessServerSend(SocketAsyncEventArgs e) 
{ 
    if (e.SocketError == SocketError.Success) 
    {     
     AsyncUserToken token = (AsyncUserToken)e.UserToken; 
     SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop(); 
     ((AsyncUserToken)readEventArgs.UserToken).Socket = token.Socket;   
     bool willRaiseEvent = token.Socket.ReceiveAsync(readEventArgs); 
     if (!willRaiseEvent) 
     { 
      ProcessServerReceive(readEventArgs); 
     } 
    } 
    else 
    { 
     CloseServerSocket(e); 
    } 
} 

そしてProcessServerReceiveはようです!送信されたメッセージが同じであることを確認しました!


更新:

応答は次のとおりです。

不正な要求 - 無効な動詞

HTTPエラー400要求動詞が無効です。

+0

に変更されました。どこでmyevをasync connectメソッドに渡しますか? – jdweng

+0

@jdweng実際に私はこのコードを使ってソケットAからデータを取得し、それを別のソケットBに送り、Bからの応答を受け取ってAに返します。 'myev'は受信専用の' SocketAsyncEventArgs'ですAからのデータはBIに接続するために新しいデータを定義しました。 – Alex

答えて

1

この問題の原因は、1024要素(1024要素の空のバッファ)で初期化されたバッファで変数SocketAsyncEventArgsを使用して接続するためです。私はこのコード行を追加することで問題を解決しました:の前にreadEventArgs.SetBuffer(0, 0);の長さのバッファを設定してください。したがって、私のReceive関数は、

private void Receive(SocketAsyncEventArgs e) 
{ 
    myev = e; 
    SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop(); 
    readEventArgs.RemoteEndPoint = remote; 
    Socket connectSocket; 
    connectSocket = new Socket(remote.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
    ((AsyncUserToken)readEventArgs.UserToken).Socket = connectSocket; 
    readEventArgs.SetBuffer(0, 0);//This line of code resolves my issue. 
    bool willRaiseEvent = connectSocket.ConnectAsync(readEventArgs);//Async Connect 
    if (!willRaiseEvent) 
    { 
     ProcessConnect(readEventArgs); 
    } 
} 
関連する問題