C++ Winsock接收到的字节数无效

C++ Winsock接收到的字节数无效,c++,c++11,winsock,C++,C++11,Winsock,在尝试验证接收的字节数时,我当前面临一个与Winsock相关的问题 在我的应用程序中,我使用一个非阻塞套接字来抛出我自己的Timeout异常。下面是初始化Winsock的相应代码: // Initialize Winsock WSAData winSockData; WORD dllVersion = MAKEWORD(2, 1); long iResult = WSAStartup(dllVersion, &winSockData); if (iResult != NO_ERROR)

在尝试验证接收的字节数时,我当前面临一个与Winsock相关的问题

在我的应用程序中,我使用一个非阻塞套接字来抛出我自己的
Timeout
异常。下面是初始化
Winsock
的相应代码:

// Initialize Winsock
WSAData winSockData;
WORD dllVersion = MAKEWORD(2, 1);
long iResult = WSAStartup(dllVersion, &winSockData);
if (iResult != NO_ERROR)
    return;

addrinfo* serverAddress = nullptr;
addrinfo* ptr = nullptr, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

iResult = getaddrinfo("127.0.0.1", "10011", &hints, &serverAddress);
if (iResult != 0)
    return;

// Create communication socket
SOCKET connectSocket = socket(AF_INET, SOCK_STREAM, /*IPPROTO_TCP*/0);
if (connectSocket == INVALID_SOCKET)
    return;

// Establish connection to server
iResult = connect(connectSocket, serverAddress->ai_addr, (int)serverAddress->ai_addrlen);
if (iResult == SOCKET_ERROR)
    return;

// Set socket to non-blocking
ULONG mode = 1;
m_iResult = ioctlsocket(m_connectSocket, FIONBIO, &mode);
if (m_iResult == SOCKET_ERROR)
    return;

// server address info not needed anymore
freeaddrinfo(serverAddress);
应用程序首先连接到给定的telnet服务器,发送请求,然后等待相应的响应消息

传入数据存储在一个适当的字符数组中,称为
m_serverMsg
(固定大小为
BUFSIZE
,当前设置为4200字节)

如果检索服务器响应消息的时间过长(存储在
g_requestTimeout
中的最大允许时间),则会抛出我自己的
TimeoutException

如果在消息缓冲区中找到换行符(
\r\n
),则给定的服务器消息已到达其结尾

但是,以下用于检索服务器响应消息的部分未按预期工作。预期的传入数据字节为
1040
,但实际字节始终为
3435973836

unsigned long long startTime = getWallTimeInMs();
bool retry = true;
unsigned int receivedBytes = 0;
// Fetch server response
do
{

    try
    {

        m_iResult = fetchMessage(m_connectSocket, m_serverMsg, int(BUFSIZE - receivedBytes));
        if (m_iResult == SOCKET_ERROR)
            throw std::exception();

        if (m_iResult > 0)
        {
            for (unsigned int i = receivedBytes; i < receivedBytes + m_iResult; i++)
            {
                char* eol = strstr(m_serverMsg, "\r\n");
                if (eol)
                {
                    retry = false;
                    break;
                }
            }

            receivedBytes += m_iResult;
        }
    }
    catch (CommException e)
    {
        // in case there's a short delay in retrieving the server response message
        if (getWallTimeInMs() - startTime < g_requestTimeout)
            Sleep(20);
        else
            // response timeout exceeded; connection has been lost
            throw CommException("server not responding in time.", CommProblem::ConnectionLost);
    }
    catch (std::exception& e)
    {
        std::cout << "There was a socket related problem." << std::endl;
        std::cout << "Error code: " << WSAGetLastError() << std::endl;
    }

} while (retry);
这部分

for (unsigned int i = receivedBytes; i < receivedBytes + m_iResult; i++)
{
    if (m_serverMsg[i] == '\r\n')
    {
        retry = false;
        break;
    }
}
或者将
m_serverMsg
转换为
std::string
并使用
find
方法

if(std::string(m_serverMsg, receivedBytes, m_iResult).find("\r\n") != std::string::npos)
{
    retry = false;
    break;
}

显示
fetchMessage
。您在
m\u iResult
中获得了
3435973836
?什么时候<代码>中断将只停止您的
循环
操作,而不停止
执行
循环。您的错误在消息中。3435973836是十六进制的0xCCCC。编译器在调试模式下使用此值填充未初始化的变量。如果需要帮助,请显示fetchMessage。在调试窗口中,它显示for
m_serverMsg
:@NikolayKondratyev
m_iResult
是一个类成员变量,每次在try{}块内都会为其赋值:
m_iResult=fetchMessage(…)
\r\n
不是“回车符”,而是两个字节的CR/LF序列。注意:在eWoldBlock上没有“连接延迟”,将其与“连接丢失”关联也是非常不正确的。很高兴知道,thx。但是接收的字节数仍然存在问题。@neuronal.bit所以
3435973836
fetchMessage
call之后
m_iResult
的值吗?这是正确的。如果
fetchMessage()
本身抛出异常,则在将接收到的字节数分配给
m_iResult
之前会捕获该异常。因此,
m_iResult
应始终包含实际接收的字节数,以防出现错误。@neuronal.bit尝试添加调试输出,例如
printf(“recv返回%d\n”,结果)recv
之后的
fetchMessage
中的code>。有趣的是,在
fetchMessage()
中,返回值是
356
,但分配给
m\u iResult
时,返回值是
3435973836
m_iResult
的类型为
int
char* eol = strstr(m_serverMsg, "\r\n");
if(eol != NULL)
{
    retry = false;
    break;
}
if(std::string(m_serverMsg, receivedBytes, m_iResult).find("\r\n") != std::string::npos)
{
    retry = false;
    break;
}