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函数需要发送到棋盘
答案 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
之前检查返回值cbBytesWritten
和WriteFile
的值,这样您就知道第一次调用成功了。
此外,请不要忘记在尺寸计算中删除sizeof(TCHAR)
部分。您永远不会在代码中使用TCHAR
。您的输入是常规char*
,因此您在条件中使用的字符串也是如此。我还建议将WriteFile
替换为WriteFileA
,以表明您正在使用此类字符。
最后,确保您的服务器实际上是从您写入的句柄中读取字节。如果您的服务器没有从句柄读取,WriteFile
函数将冻结,直到它可以再次写入句柄。