沟通c程序和PHP

时间:2011-01-25 03:33:40

标签: php c communication exec

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

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

4 个答案:

答案 0 :(得分:6)

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

Redis的

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

修改example.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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”。如果你问我,就像馅饼一样容易:)。

命名管道

您可以使用named pipes

套接字

您可以阅读Beej's Guide to Network Programming Using Internet Sockets。在我看来,这是一个非常好的阅读。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

您可以使用命名管道。

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

答案 3 :(得分:0)

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

client.php

#include <stdio.h>
#include <sys/un.h>
#include <sys/socket.h>

#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");
  }

}

server.c

public static boolean sumThree(int[] myArray) {
    int sum = 0;
    for (int i = 3; i < myArray.length; i++) {
        sum += myArray[i];
    }
    int sumof3E = myArray[0] + myArray[1] + myArray[2];
    if (sum > sumof3E) {
        return true;
    }
    else {
        return false;
    }
}