C++ Winsock非阻塞发送()等待缓冲区。正确的方法是什么?

C++ Winsock非阻塞发送()等待缓冲区。正确的方法是什么?,c++,buffer,winsock,send,nonblocking,C++,Buffer,Winsock,Send,Nonblocking,我对何时需要将数据存储在等待缓冲区(等待FD_写入事件)有一些疑问 这是我的发送功能(已修复): bool MyClass::DataSend(char*buf,int len) { if(len0) { 如果((m_SendBufferLen+len)0) { nPosition+=iResult; nLeft-=iResult; } 其他的 { //已发送日志0字节 打破 } } 其他的 { if(WSAGetLastError()==WSAEWOULDBLOCK) { if((m_Send

我对何时需要将数据存储在等待缓冲区(等待FD_写入事件)有一些疑问

这是我的发送功能(已修复):

bool MyClass::DataSend(char*buf,int len)
{
if(len0)
{
如果((m_SendBufferLen+len)0)
{
nPosition+=iResult;
nLeft-=iResult;
}
其他的
{
//已发送日志0字节
打破
}
}
其他的
{
if(WSAGetLastError()==WSAEWOULDBLOCK)
{
if((m_SendBufferLen+nLeft)0)
{
memmove(m_SendBuffer,(m_SendBuffer+nPosition),(m_SendBufferLen-nPosition));
m_SendBufferLen-=n位置;
}
打破
}
其他的
{
//关闭连接并记录winsock错误
返回false;
}
}
如果(nLeft 0)
或否?如何模拟此场景?是否有可能send()在非阻塞模式下发送的字节数少于请求的字节数?如果没有,为什么使用while()循环

  • 这是最后的代码(感谢@user315052)

在while循环的顶部,您已经在递减
nLeft
,因此不需要从中减去
nPosition

iResult = send(m_Socket, (char*)(buf + nPosition), nLeft, 0);
在第二个函数中,当您将未发送的字节移到数组的开头时,应该使用
memmove
,因为您有重叠的区域(您正在将
m_SendBuffer
的区域复制到自身中)。重叠如下图所示,其中一些
a
将被复制到自身中

m_SendBuffer: [XXXXAAAAAAAAAAAA]
mPosition: 4
nLeft: 12
我对为什么
DataSend()有点困惑
的实现允许调用方在遇到
WSAEWOULDBLOCK
时继续成功调用它。我建议修改接口以返回一个结果,让调用方知道它应该停止发送,并等待恢复发送的指示

您不需要
n位置>0
检查

您可以通过让数据接收器不读取任何内容来强制发生这种情况


在非阻塞模式下,
send
发送的字节数肯定会比请求的字节数少。

谢谢,伙计。DataSend()的原因是允许呼叫方继续呼叫是因为这是一个游戏服务器,他自己没有处理请求,所以他将数据发送到另一个连接到SQL数据库的进程等。游戏服务器等待外部进程响应以允许玩家登录等。您好,请检查我的发送(FD_写入事件)第一篇文章是正确的。我也在第一个函数中做了修复…另一个问题。我需要使用memmove而不是memcpy来重新定位
DataSendEvent()中的缓冲区
?@youngrp:在
DataSendEvent
中,使用
memmove
,而不是
memcpy
。我更新了帖子,谢谢。非常感谢!只需将
memcpy
更改为
memmove
,其他一切都好吗?你认为呢?
iResult = send(m_Socket, (char*)(buf + nPosition), nLeft, 0);
m_SendBuffer: [XXXXAAAAAAAAAAAA]
mPosition: 4
nLeft: 12