tangbinde 发表于 2017-4-12 11:09:22

PHP服务器端通过命名管道与C/C++程序通信

  在这几天的工作过程中,需要实现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 = {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);
}
页: [1]
查看完整版本: PHP服务器端通过命名管道与C/C++程序通信