进程管道通信出现乱码,请指导一下
如题,我在写进程通过管道通信的时候,遇到进程通信消息不稳定的情况,它的 消息内容有时候是完全正常的,有时候却会出现乱码这里// SendMessage.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hRead ;
HANDLE hWrite ;
SECURITY_ATTRIBUTES sa ;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE ; //指定管道句柄可被继承
BOOL bRet = CreatePipe(&hRead,&hWrite,&sa,0); //创建匿名管道
if(bRet == TRUE){
printf("成功创建匿名管道\n");
}else{
printf("创建匿名管道失败,%d\n",GetLastError());
}
HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE);//获得本进程当前标准输出,以备将来恢复
SetStdHandle(STD_OUTPUT_HANDLE,hWrite);
STARTUPINFO si;
GetStartupInfo(&si) ;
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = TRUE ;
TCHAR szCommandLine[] = TEXT("C:\\代码\\管道通信\\Client\\Debug\\Client.exe");
bRet = CreateProcess(NULL,szCommandLine,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi);
SetStdHandle(STD_OUTPUT_HANDLE,hTemp); //恢复本进程标准输出
if (bRet == TRUE){
printf("创建子进程成功\n");
}else{
printf("创建子进程失败,错误代码:%d\n",GetLastError());
}
char ReadBuf={0};
DWORD ReadNum;
do{
ZeroMemory(ReadBuf,100);
BOOL bRet = ReadFile(hRead,ReadBuf,100,&ReadNum,NULL);
ReadBuf = '\0';
printf("从管道读取%d字节数据:[%s]\n",ReadNum,ReadBuf);
} while (bRet);
if (GetLastError() == ERROR_BROKEN_PIPE){
printf("管道被子进程关闭\n");
}else{
printf("读取数据错误,错误代码%d\n",GetLastError());
}
return 0;
}
消息端
// Client.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
for (int i = 0 ;i < 10 ; i++){
printf("i = %d;",i);
cout<<"标准输出"<<i<<endl;
cerr<<"标准错误"<<i<<endl;
}
system("pause");
return 0;
}
附上我的源码,希望有人可以帮助一下我。
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#define BUFSIZE 4096
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
HANDLE g_hInputFile = NULL;
void CreateChildProcess(void);
void WriteToPipe(void);
void ReadFromPipe(void);
void ErrorExit(PTSTR);
int _tmain(int argc, TCHAR *argv[])
{
SECURITY_ATTRIBUTES saAttr;
printf("\n->Start of parent execution.\n");
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
ErrorExit(TEXT("StdoutRd CreatePipe"));
// Ensure the read handle to the pipe for STDOUT is not inherited.
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stdout SetHandleInformation"));
// Create a pipe for the child process's STDIN.
if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
ErrorExit(TEXT("Stdin CreatePipe"));
// Ensure the write handle to the pipe for STDIN is not inherited.
if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stdin SetHandleInformation"));
// Create the child process.
CreateChildProcess();
// Get a handle to an input file for the parent.
// This example assumes a plain text file and uses string output to verify data flow.
if (argc == 1)
ErrorExit(TEXT("Please specify an input file.\n"));
g_hInputFile = CreateFile(
argv,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY,
NULL);
if ( g_hInputFile == INVALID_HANDLE_VALUE )
ErrorExit(TEXT("CreateFile"));
// Write to the pipe that is the standard input for a child process.
// Data is written to the pipe's buffers, so it is not necessary to wait
// until the child process is running before writing data.
WriteToPipe();
printf( "\n->Contents of %s written to child STDIN pipe.\n", argv);
// Read from pipe that is the standard output for child process.
printf( "\n->Contents of child process STDOUT:\n\n", argv);
ReadFromPipe();
printf("\n->End of parent execution.\n");
// The remaining open handles are cleaned up when this process terminates.
// To avoid resource leaks in a larger application, close handles explicitly.
return 0;
}
void CreateChildProcess()
// Create a child process that uses the previously created pipes for STDIN and STDOUT.
{
TCHAR szCmdline[]=TEXT("child");
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bSuccess = FALSE;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.hStdInput = g_hChildStd_IN_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
bSuccess = CreateProcess(NULL,
szCmdline, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo,// STARTUPINFO pointer
&piProcInfo);// receives PROCESS_INFORMATION
// If an error occurs, exit the application.
if ( ! bSuccess )
ErrorExit(TEXT("CreateProcess"));
else
{
// Close handles to the child process and its primary thread.
// Some applications might keep these handles to monitor the status
// of the child process, for example.
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
}
}
void WriteToPipe(void)
// Read from a file and write its contents to the pipe for the child's STDIN.
// Stop when there is no more data.
{
DWORD dwRead, dwWritten;
CHAR chBuf;
BOOL bSuccess = FALSE;
for (;;)
{
bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL);
if ( ! bSuccess || dwRead == 0 ) break;
bSuccess = WriteFile(g_hChildStd_IN_Wr, chBuf, dwRead, &dwWritten, NULL);
if ( ! bSuccess ) break;
}
// Close the pipe handle so the child process stops reading.
if ( ! CloseHandle(g_hChildStd_IN_Wr) )
ErrorExit(TEXT("StdInWr CloseHandle"));
}
void ReadFromPipe(void)
// Read output from the child process's pipe for STDOUT
// and write to the parent process's pipe for STDOUT.
// Stop when there is no more data.
{
DWORD dwRead, dwWritten;
CHAR chBuf;
BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
for (;;)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
if( ! bSuccess || dwRead == 0 ) break;
bSuccess = WriteFile(hParentStdOut, chBuf,
dwRead, &dwWritten, NULL);
if (! bSuccess ) break;
}
}
void ErrorExit(PTSTR lpszFunction)
// Format a readable error message, display a message box,
// and exit from the application.
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(1);
}
子进程文件
#include <windows.h>
#include <stdio.h>
#define BUFSIZE 4096
int main(void)
{
CHAR chBuf;
DWORD dwRead, dwWritten;
HANDLE hStdin, hStdout;
BOOL bSuccess;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (
(hStdout == INVALID_HANDLE_VALUE) ||
(hStdin == INVALID_HANDLE_VALUE)
)
ExitProcess(1);
// Send something to this process's stdout using printf.
printf("\n ** This is a message from the child process. ** \n");
// This simple algorithm uses the existence of the pipes to control execution.
// It relies on the pipe buffers to ensure that no data is lost.
// Larger applications would use more advanced process control.
for (;;)
{
// Read from standard input and stop on error or no data.
bSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);
if (! bSuccess || dwRead == 0)
break;
// Write to standard output and stop on error.
bSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL);
if (! bSuccess)
break;
}
return 0;
}
我要去学校了,你先看 正在给你写代码中,估计现在时间不够了,下午还要去学校呢。 freeparty 发表于 2015-4-28 11:05
我要去学校了,你先看
辛苦江江了,我还得研究一下你的这个代码。昨天晚上去讨论比赛的事情去了。谢谢江江啦 学习 学习下 我只是路过打酱油的。 哇~这个好!!! 我是来领鱼币的
页:
[1]