用无名管道重定向子进程的输入输出


PipeServer:

// 开启管道服务器
int StartPipeServer(int Size,char style,TCHAR *path)
{
	PipeElem item;
	SECURITY_ATTRIBUTES saAttr;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	TCHAR lpszComCmdLine[] = L"UsbSpeedTestTool.exe";
	TCHAR lpszCmdLine[256];
	char strMsg[64];

	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	saAttr.bInheritHandle = TRUE;
	saAttr.lpSecurityDescriptor = NULL;

	if(!CreatePipe(&item.hStdInRead,&item.hStdInWrite,&saAttr,0))
	{
		LoadStringA(NULL,IDS_CREATE_PIPE_FAILED1,strMsg,64);
		printf("%s %d\n",strMsg,GetLastError());
		return -1;
	} 
	if(!CreatePipe(&item.hStdOutRead,&item.hStdOutWrite,&saAttr,0))
	{
		LoadStringA(NULL,IDS_CREATE_PIPE_FAILED2,strMsg,64);
		printf("%s %d\n",strMsg,GetLastError());
		return -1;
	}
	if(!DuplicateHandle(GetCurrentProcess(),item.hStdOutWrite,GetCurrentProcess(),&item.hStdErrWrite,0,TRUE,DUPLICATE_SAME_ACCESS))
	{
		LoadStringA(NULL,IDS_DUPLICATE_PIPE_FAILED,strMsg,64);
		printf("%s %d\n",strMsg,GetLastError());
		return -1;
	}
	item.iNum = giClientNum++;
	item.usbPath = path;
	AddPipeNode(glistPipe,item);
	DWORD id;
	HANDLE hThread =  CreateThread(NULL,0,ReadFromClientPipeThread,(LPVOID)item.iNum,0,&id);
	if(hThread == NULL)
	{
		LoadStringA(NULL,IDS_CREATE_THREAD_FAILED,strMsg,64);
		printf("%s %d\n",strMsg,GetLastError());
		return -1;
	}
	LoadStringA(NULL,IDS_CREATE_THREAD_READPIPE,strMsg,64);
	printf("%s, thread id=%d\n",strMsg,id);

	wsprintf(lpszCmdLine,L"%s %d %c %s",lpszComCmdLine,Size,style,path);
	//wprintf(_T("CmdLine:%s\n"),lpszCmdLine);
	ZeroMemory(&si,sizeof(si));
	si.cb = sizeof(STARTUPINFO);
	si.dwFlags |= STARTF_USESTDHANDLES;
	si.dwFlags |= STARTF_USESHOWWINDOW;
	si.hStdOutput = item.hStdOutWrite;   // 子进程的stdout输出到hStdOutWrite
	si.hStdError  = item.hStdErrWrite;   // 子进程的stderr输出到hStdErrWrite
	si.hStdInput  = item.hStdInRead;

	hStdInRead = item.hStdInWrite;

	if(!CreateProcess(NULL,lpszCmdLine,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))
	{
		LoadStringA(NULL,IDS_CREATE_PROCESS_FAILED,strMsg,64);
		printf("%s %d\n",strMsg,GetLastError());
		return -1;
	}
	return 0;
}
// 写入stdin
BOOL WriteToPipe(char *inbuff,HANDLE hPipe)
{
	DWORD dwWritten;
	BOOL bSuccess = WriteFile(hPipe,inbuff,strlen(inbuff),&dwWritten,NULL);

	if(bSuccess) return true;
	else 
	{
		char strMsg[32];
		LoadStringA(NULL,IDS_WRITEFILE_FAILED,strMsg,32);
		printf("%s %d\n",strMsg,GetLastError());
		return false;
	}
}

// 读出stdout
BOOL ReadFromPipe(char *outbuff,HANDLE hPipe)
{
	DWORD dwRead = 0;
	memset(outbuff,0,sizeof(outbuff));
	if(ReadFile(hPipe,outbuff,255,&dwRead,NULL))
	{
		return true;
	}
	else
	{
		char strMsg[32];
		LoadStringA(NULL,IDS_READFILE_FAILED,strMsg,32);
		printf("%s %d\n",strMsg,GetLastError());
		return false;		
	}
}

// 从管道读取数据线程
DWORD CALLBACK ReadFromClientPipeThread(LPVOID lpvParam)
{
	switch(giLangSel)
	{
	case 1:SetThreadUILanguage(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED));break;
	case 2:SetThreadUILanguage(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US));break;
	}
	char strMsg[64];
	char strbuf[256]="";
	int num = (int)lpvParam;
	HANDLE hPipe = GetReadOutHandleByNum(glistPipe,num);
	if(hPipe == NULL)
	{
		LoadStringA(NULL,IDS_GET_READOUT_FAILED,strMsg,64);
		printf("%s\n",strMsg);
		return 0;
	}
	char recvbuf[256]="";

	DWORD dwLen = 0;
	int iSend = 0;
	while(ReadFile(hPipe,recvbuf,256,&dwLen,NULL))
	{
		LoadStringA(NULL,IDS_RECV_FROM_,strMsg,64);
		CharCut(recvbuf);
		iSend = send(sockConn,recvbuf,strlen(recvbuf)+1,0);
		if(iSend == SOCKET_ERROR)
		{
			LoadStringA(NULL,IDS_RECVFROM_PIPE_SEND_ERR,strMsg,64);
			printf("%s %d\n",strMsg,GetLastError());
			break;
		}
		if(mySubstrFind(recvbuf,"done") >= 0)
		{
			printf("\n%s %d:%s\n",strMsg,num,recvbuf);
			int iSend = send(sockConn,"[done]",7,0);
			if(iSend <= 0)
			{
				LoadStringA(NULL,IDS_RECVFROM_PIPE_SEND_DONE_FAILED,strMsg,64);
				printf("%s %d\n",strMsg,GetLastError());
			}
			break;
		}
		else
		{
			sprintf_s(strbuf,256,"%s %d:%s",strMsg,num,recvbuf);
			OneLineOutput(strbuf);
		}
		memset(recvbuf,'\0',sizeof(recvbuf));
	}
	LoadStringA(NULL,IDS_RECVFROM_PIPE_THREAD_QUIT,strMsg,64);
	printf("%s\n",strMsg);
	return 0;
}



PipeClient:

1.只要读取stdin,和写入stdout。字符串后面加上'\n'。

2.如果管道服务器还是不能及时收到数据,用fflush(stdout);

3.管道中有数据时子进程不能退出,否则服务器收不到数据。

4.客户端退出时可以略微延时

















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值