简体   繁体   English

沟通c程序和PHP

[英]communicate c program and php

I want to have a web page (written in php because it's what i know) that displays an input value. 我想要一个显示输入值的网页(用PHP编写,因为它是我所知道的)。 I want that value to be passed to ac programa that's already running. 我希望将该值传递给已经运行的ac程序。

I though of using sockets to communicate between both process, but how do I manage to do that? 我虽然使用套接字在两个进程之间进行通信,但我该如何设法做到这一点? how can I use fsockopen to connect to a local socket. 如何使用fsockopen连接到本地套接字。

Some simple solutions I can think of are: 我能想到的一些简单的解决方案是:

Redis Redis的

You could use redis as your ipc using hiredis as your c client library. 您可以使用redis作为您的ipc,使用hiredis作为您的c客户端库。 I never used hiredis library before but did it just now for you to test and the library is really good. 我以前从未使用过hiredis库,但是刚刚做了测试,库真的很棒。 I could have known it because redis is the best piece of C code I know :). 我可以知道它,因为redis是我知道的最好的C代码:)。

modify example.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;
}

Compile and run example: 编译并运行示例:

make
./hiredis-example

from ./redis-cli: 来自./redis-cli:

from another tab start start redis-cli(for prototyping) and issue the following command. 从另一个选项卡开始启动redis-cli(用于原型设计)并发出以下命令。 You should replace this with predis as php client library, but that is going to be very easy: 您应该将此替换为predis作为php客户端库,但这将非常简单:

lpush php "Hello from PHP"

Inside running hiredis-example: 在里面运行hiredis-example:

You should see the message "Hello from PHP". 您应该看到消息“来自PHP的Hello”。 Easy as pie if you ask me :). 如果你问我:)就像馅饼一样容易。

Named pipes 命名管道

You could use a named pipes . 您可以使用命名管道

Sockets 套接字

You could read the Beej's Guide to Network Programming Using Internet Sockets . 您可以阅读Beej的使用Internet套接字进行网络编程的指南 In my opinion this is a very good read. 在我看来,这是一个非常好的阅读。

A local socket is just a file, you'd use fopen() , fwrite() , and fclose() on it, as usual. 本地套接字只是一个文件,你可以像往常一样使用fopen()fwrite()fclose() The only difference is that you're reading from (or writing to) another process, instead of a file on disk somewhere. 唯一的区别是你正在读取(或写入)另一个进程,而不是某处某个磁盘上的文件。

You can use a named pipe. 您可以使用命名管道。

  1. Once the external program starts running (or before that), you make sure the named pipe exists. 一旦外部程序开始运行(或之前),您就确保命名管道存在。 See mkfifo . mkfifo
  2. Open the pipe for reading in the external program (just like you open a regular file). 打开管道以便在外部程序中读取(就像打开常规文件一样)。
  3. Start reading the pipe. 开始阅读管道。 By default, the program will block until it has data to read. 默认情况下,程序将阻塞,直到有数据要读取。
  4. Open the pipe for writing in the PHP script (again, just like you would open a regular file). 打开管道以便在PHP脚本中写入(再次,就像打开常规文件一样)。
  5. Write data to the pipe. 将数据写入管道。 The external program will now get this data. 外部程序现在将获取此数据。

Here is a working example where the php script sends a request to a C daemon and then waits for the response. 这是一个工作示例,其中php脚本向C守护程序发送请求,然后等待响应。 It uses Unix domain sockets in datagram mode so it is fast. 它在数据报模式下使用Unix域套接字,因此速度很快。

client.php client.php

<?php

$file = "/tmp/myclient.sock";
unlink($file);

$socket = socket_create(AF_UNIX, SOCK_DGRAM, 0);

if (socket_bind($socket, $file) === false) {
  echo "bind failed";
}

socket_sendto($socket, "Hello world!", 12, 0, "/tmp/myserver.sock", 0);
echo "sent\n";

if (socket_recvfrom($socket, $buf, 64 * 1024, 0, $source) === false) {
  echo "recv_from failed";
}
echo "received: [" . $buf . "]   from: [" . $source . "]\n";

?>

server.c server.c

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM