我想使用套接字连接到服务。当我使用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/