沟通c程序和PHP

我想要一个显示输入值的网页(用PHP编写,因为它是我所知道的)。 我希望将该值传递给已经运行的ac程序。

我虽然使用套接字在两个进程之间进行通信,但我该如何设法做到这一点? 如何使用fsockopen连接到本地套接字。

我能想到的一些简单的解决方案是:

Redis的

您可以使用redis作为您的ipc,使用hiredis作为您的c客户端库。 我以前从未使用过hiredis库,但是刚刚做了测试,库真的很棒。 我可以知道它,因为redis是我知道的最好的C代码:)。

修改example.c

#include  #include  #include  #include "hiredis.h" int main(void) { redisContext *c; redisReply *reply; c = redisConnect((char*)"127.0.0.1", 6379); if (c->err) { printf("Connection error: %s\n", c->errstr); redisFree(c); exit(1); } /* Blocking pop. */ reply = redisCommand(c, "BLPOP php 0"); if (reply->type == REDIS_REPLY_ARRAY) { if (reply->elements == 2) { printf("%s\n", reply->element[1]->str); } } freeReplyObject(reply); redisFree(c); return 0; } 

编译并运行示例:

 make ./hiredis-example 

来自./redis-cli:

从另一个选项卡开始启动redis-cli(用于原型设计)并发出以下命令。 您应该将此替换为predis作为php客户端库,但这将非常简单:

 lpush php "Hello from PHP" 

在内部运行hiredis-example:

您应该看到消息“来自PHP的Hello”。 如果你问我:)就像馅饼一样容易。

命名管道

您可以使用命名管道 。

套接字

您可以阅读Beej的使用Internet套接字进行网络编程指南 。 在我看来,这是一个非常好的阅读。

本地套接字只是一个文件,你可以像往常一样使用fopen()fwrite()fclose() 。 唯一的区别是你正在读取(或写入)另一个进程,而不是某个地方的磁盘上的文件。

您可以使用命名管道。

  1. 一旦外部程序开始运行(或之前),您就确保命名管道存在。 见mkfifo 。
  2. 打开管道以便在外部程序中读取(就像打开常规文件一样)。
  3. 开始阅读管道。 默认情况下,程序将阻塞,直到有数据要读取。
  4. 打开管道以便在PHP脚本中写入(再次,就像打开常规文件一样)。
  5. 将数据写入管道。 外部程序现在将获取此数据。

这是一个工作示例,其中php脚本向C守护程序发送请求,然后等待响应。 它在数据报模式下使用Unix域套接字,因此速度很快。

client.php

  

server.c

 #include  #include  #include  #define SOCKET_FILE "/tmp/myserver.sock" #define BUF_SIZE 64 * 1024 int main() { struct sockaddr_un server_address = {AF_UNIX, SOCKET_FILE}; int sock = socket(AF_UNIX, SOCK_DGRAM, 0); if (sock <= 0) { perror("socket creation failed"); return 1; } unlink(SOCKET_FILE); if (bind(sock, (const struct sockaddr *) &server_address, sizeof(server_address)) < 0) { perror("bind failed"); close(sock); return 1; } for (;;) { struct sockaddr_un client_address; int i, numBytes, len = sizeof(struct sockaddr_un); char buf[BUF_SIZE]; numBytes = recvfrom(sock, buf, BUF_SIZE, 0, (struct sockaddr *) &client_address, &len); if (numBytes == -1) puts("recvfrom failed"); printf("Server received %d bytes from %s\n", numBytes, client_address.sun_path); for (i = 0; i < numBytes; i++) buf[i] = toupper((unsigned char) buf[i]); if (sendto(sock, buf, numBytes, 0, (struct sockaddr *) &client_address, len) != numBytes) puts("sendto failed"); } }