康小泡 发表于 2015-4-28 11:05:25

进程管道通信出现乱码,请指导一下

如题,我在写进程通过管道通信的时候,遇到进程通信消息不稳定的情况,它的 消息内容有时候是完全正常的,有时候却会出现乱码


这里// 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;
}





附上我的源码,希望有人可以帮助一下我。

freeparty 发表于 2015-4-28 11:05:26

#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 13:17:39

正在给你写代码中,估计现在时间不够了,下午还要去学校呢。

angel2015 发表于 2015-4-29 01:26:51

康小泡 发表于 2015-4-29 08:24:53

freeparty 发表于 2015-4-28 11:05
我要去学校了,你先看

辛苦江江了,我还得研究一下你的这个代码。昨天晚上去讨论比赛的事情去了。谢谢江江啦

likeangel 发表于 2015-4-29 10:24:08

shiba 发表于 2015-4-29 11:37:27

学习

likeangel 发表于 2015-4-29 14:46:30

shiba 发表于 2015-4-29 17:34:06

学习下

angel2015 发表于 2015-4-30 02:09:44

k2012 发表于 2015-4-30 02:12:34

我只是路过打酱油的。

Ryans 发表于 2015-4-30 21:50:07

哇~这个好!!!

y290176346 发表于 2015-9-23 21:29:58

我是来领鱼币的
页: [1]
查看完整版本: 进程管道通信出现乱码,请指导一下