c# - Socket.ConnectAsync收到400错误请求,而Socket.Connect获得200正常

标签 c# .net sockets

我想使用套接字连接到服务。当我使用Socket.Connect时,响应为200 ok,并且可以成功接收数据,但是当我使用Socket.ConnectAsync时,响应为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的代码:
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。请求谓词无效。

最佳答案

出现此问题的原因是由于使用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);
    }
}

关于c# - Socket.ConnectAsync收到400错误请求,而Socket.Connect获得200正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41522419/

相关文章:

c# - 在c# mono应用程序中通过localhost/127.0.0.1 mysql连接到本地MariaDB MySQL Linux服务器的问题

c# - 如何使用 LINQ 延迟加载 where 条件

c# - 当子项打开时禁用 MDI 窗体的控件

java - 从android中的Socket读取数据

PHP 套接字服务器占用大量 CPU 资源

c# - .NET 项目的最佳开源项目托管站点

c# - 使用 Visual C# 2010 Express 在 C# 项目中添加引用 'SHDocVw'

c# - 在 C# 中动态覆盖任何方法

c# - 仅向管理员授予对特殊表单的访问权限

android - 连接两个仿真器以在它们之间建立Socket连接