【问题标题】:Socket.ConnectAsync receives 400 bad request while Socket.Connect gets 200 okSocket.ConnectAsync 收到 400 错误请求,而 Socket.Connect 获得 200 ok
【发布时间】:2017-01-07 14:21:55
【问题描述】:

我想使用套接字连接到服务。当我使用 Socket.Connect 时,响应是 200 ok,我可以成功接收数据,但是当我使用 Socket.ConnectAsync 时,响应是 400 bad request。

这里是 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 的代码:

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);
    }
}

请注意,我们已将 m_readWritePool 定义为 SocketAsyncEventArgsPool m_readWritePool; 并填充了 1000 个项目。

我们已将ProcessServerSend 定义为:

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 是:

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);
    }
}

请注意,除了连接方法之外,所有功能都相同!我检查了发送的消息是否相同!


更新:

回复是:

错误请求 - 无效动词

HTTP 错误 400。请求动词无效。

【问题讨论】:

  • 你在哪里将 myev 传递给异步连接方法?
  • @jdweng 实际上我正在使用此代码从套接字 A 获取数据并将其发送到另一个套接字 B 并接收来自 B 的响应并将其发送回 A。myev 是一个 @ 987654330@专门用于接收来自A的数据,所以为了连接到B我定义了一个新的。

标签: c# .net sockets


【解决方案1】:

此问题的原因是由于使用SocketAsyncEventArgs 变量与由 1024 个元素初始化的缓冲区(1024 个元素空缓冲区)进行连接。我通过添加这行代码解决了这个问题:readEventArgs.SetBuffer(0, 0);Async Connect 设置零长度缓冲区之前。所以,我的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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 2021-01-21
    • 2011-03-28
    • 1970-01-01
    相关资源
    最近更新 更多