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.客户端退出时可以略微延时