Я хочу иметь веб-страницу (написанную на php, потому что это то, что я знаю), которая отображает входное значение. Я хочу, чтобы это значение передавалось в ac-программу, которая уже запущена.
Хотя я использую сокеты для связи между обоими процессами, но как мне это удается? как я могу использовать fsockopen для подключения к локальному сокету.
Некоторые простые решения, о которых я могу думать, это:
Вы можете использовать redis как свой ipc, используя hiredis в качестве вашей клиентской библиотеки c. Я никогда раньше не использовал библиотеку 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:
Вы должны увидеть сообщение «Hello from PHP». Легко, как пирог, если вы спросите меня :).
Вы можете использовать именованные каналы .
Вы можете прочитать руководство Beej по сетевому программированию с использованием интернет-сокетов . По-моему, это очень хорошее чтение.
Локальный сокет – это всего лишь файл, вы должны использовать fopen()
, fwrite()
и fclose()
на нем, как обычно. Единственное различие заключается в том, что вы читаете (или записываете) другой процесс, а не файл на диске где-то.
Вы можете использовать именованный канал.
Вот рабочий пример, где php-скрипт отправляет запрос на C-демон и затем ждет ответа. Он использует сокеты домена Unix в режиме дейтаграмм, поэтому он работает быстро.
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"); } }