写两次writefile函数

时间:2015-12-19 13:13:54

标签: c++ windows chess writefile

bool sendMessageToGraphics(char* msg)
    {
        //char ea[] = "SSS";
        char* chRequest = msg;  // Client -> Server
        DWORD cbBytesWritten, cbRequestBytes;

        // Send one message to the pipe.

        cbRequestBytes = sizeof(TCHAR) * (lstrlen(chRequest) + 1);

        if (*msg - '8' == 0)
        {
            char new_msg[1024] = { 0 };
            string answer = "0" + '\0';
            copy(answer.begin(), answer.end(), new_msg);
            char *request = new_msg;
            WriteFile(hPipe, request, cbRequestBytes, &cbRequestBytes, NULL);

        }

        BOOL bResult = WriteFile(           // Write to the pipe.
            hPipe,                      // Handle of the pipe
            chRequest,                  // Message to be written
            cbRequestBytes,             // Number of bytes to writ
            &cbBytesWritten,            // Number of bytes written
            NULL);                      // Not overlapped 

        if (!bResult/*Failed*/ || cbRequestBytes != cbBytesWritten/*Failed*/)
        {
            _tprintf(_T("WriteFile failed w/err 0x%08lx\n"), GetLastError());
            return false;
        }

        _tprintf(_T("Sends %ld bytes; Message: \"%s\"\n"),
            cbBytesWritten, chRequest);

        return true;

    }

运行后的第一个writefile(如果是'8'),另一个writefile函数不能正常工作,有人能理解为什么吗? sendMessageToGraphics函数需要发送到棋盘

1 个答案:

答案 0 :(得分:1)

您的代码中存在两个问题:

首先,在条件语句中初始化字符串时会出现(次要)问题。你初始化它是这样的:

string answer = "0" + '\0';

这不符合你的想法。它将使用operator+const char*作为参数类型来调用char。这将执行指针添加,将'\0'的值添加到存储常量的位置。由于'\0'将转换为0的整数值,因此不会向常量添加任何内容。但是你的字符串最终没有'\0'终止符。您可以通过将语句更改为:

来解决此问题
string answer = std::string("0") + '\0';

但真正的问题在于你使用大小变量的方式。首先将size变量初始化为输入变量的字符串长度(包括终止'\0'字符)。然后在条件语句中创建一个新传递给WriteFile的字符串,但仍然使用原始大小。这可能会导致缓冲区溢出,这是未定义的行为。您还可以将size变量设置为写入文件的字节数。然后在下一次调用中再次使用相同的值。你永远不会真正检查这个值,所以这可能会导致问题。

更改此设置的最简单方法是确保正确设置尺寸。例如,您可以执行此操作,而不是第一次调用:

WriteFile(hPipe, request, answer.size(), &cbBytesWritten, NULL);

然后在下次调用WriteFile之前检查返回值cbBytesWrittenWriteFile的值,这样您就知道第一次调用成功了。

此外,请不要忘记在尺寸计算中删除sizeof(TCHAR)部分。您永远不会在代码中使用TCHAR。您的输入是常规char*,因此您在条件中使用的字符串也是如此。我还建议将WriteFile替换为WriteFileA,以表明您正在使用此类字符。

最后,确保您的服务器实际上是从您写入的句柄中读取字节。如果您的服务器没有从句柄读取,WriteFile函数将冻结,直到它可以再次写入句柄。