communicate c program and php

后端 未结 4 1493
悲&欢浪女
悲&欢浪女 2020-12-03 09:14

I want to have a web page (written in php because it\'s what i know) that displays an input value. I want that value to be passed to a c programa that\'s already running.

相关标签:
4条回答
  • 2020-12-03 09:58

    A local socket is just a file, you'd use fopen(), fwrite(), and fclose() on it, as usual. The only difference is that you're reading from (or writing to) another process, instead of a file on disk somewhere.

    0 讨论(0)
  • 2020-12-03 10:01

    Here is a working example where the php script sends a request to a C daemon and then waits for the response. It uses Unix domain sockets in datagram mode so it is fast.

    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

    #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");
      }
    
    }
    
    0 讨论(0)
  • 2020-12-03 10:05

    Some simple solutions I can think of are:

    Redis

    You could use redis as your ipc using hiredis as your c client library. I never used hiredis library before but did it just now for you to test and the library is really good. I could have known it because redis is the best piece of C code I know :).

    modify 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:

    from another tab start start redis-cli(for prototyping) and issue the following command. You should replace this with predis as php client library, but that is going to be very easy:

    lpush php "Hello from PHP"
    

    Inside running hiredis-example:

    You should see the message "Hello from PHP". 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. In my opinion this is a very good read.

    0 讨论(0)
  • 2020-12-03 10:14

    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.
    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).
    5. Write data to the pipe. The external program will now get this data.
    0 讨论(0)
提交回复
热议问题