在这几天的工作过程中,需要实现PHP在服务器端能与其他程序通信。和老何俩人研究了半天,终于大致弄出了一个用WINDOWS的命名管道通信的方法。
有几点需要注意的:
PHP服务器端我们每次都是重新挂接命名管道。(这样写,PHP端代码量极其少,而且也很方便。)
那么我们用C/C++写的命名管道服务器则需要每次通信都创建一次管道(方法很恶心,但是暂时能实现,而且对效率要求不是那么高。我们就这么用了。)
如果不是每次都创建管道的话,会出现109错误——这个问题我们调了N久……
还有一个时序问题,在管道SERVER端每次关闭后,需要等PHP端从管道中取完数据,再重新创建管道。(此处我们为图方便,暂时用的sleep。)
下面给出例子:
PHP客户端
function Pipe($msg) { $fp = @fopen("////.//pipe//tongxun", 'w+r+b'); @fwrite($fp,$msg);//写 $result = @fread($fp,256);//读 fclose($fp); }
C++服务器端
while(1) { // 创建管道服务器 char strPipeName[] = "////.//pipe//tongxun"; char szBuf[1024] = {0}; DWORD dwRead ; DWORD userID; char cmd; PSECURITY_DESCRIPTOR psd; psd = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION)) { LocalFree((HLOCAL)psd); return -1; } if (!SetSecurityDescriptorDacl(psd, TRUE, (PACL)NULL, FALSE)) { LocalFree((HLOCAL)psd); return -1; } SECURITY_ATTRIBUTES saAttr; saAttr.nLength =sizeof(SECURITY_ATTRIBUTES); saAttr.lpSecurityDescriptor = psd; saAttr.bInheritHandle = TRUE; HANDLE hIPC = CreateNamedPipe(strPipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 0, 0, 1000, &saAttr); if (hIPC == INVALID_HANDLE_VALUE) { return -1; } // 连接管道 ConnectNamedPipe(hIPC, NULL); // 从管道读取信息 if (!ReadFile(hIPC, szBuf, sizeof(szBuf), &dwRead, 0)) { break; } //处理读到的数据szBuf... .... //写数据... //如WriteFile(hIPC, msg, strlen(msg), &dwWrite, NULL) CloseHandle(hIPC); Sleep(100); }