In C su Linux, come dovrei utilizzare 2 programmi, quest'ultimo inviando dati di testo al primo visualizzato utilizzando STDOUT?
-
28-10-2019 - |
Domanda
Sto scrivendo un semplice messaggeria istantanea programma in C su Linux.
In questo momento ho un programma che lega una presa a una porta sulla macchina locale e ascolta il testo Dati inviati da un altro programma connesso alla mia macchina IP e porta locale.
Bene, posso avere questo client inviare dati di testo al mio programma e farlo visualizzare utilizzando stdout
sulla mia macchina locale; tuttavia, io Impossibile programmare un modo per inviare i dati alla macchina client, perché il mio programma è impegnato ad ascoltare e visualizzare il testo inviato dalla macchina client.
Come dovrei creare un nuovo processo (che ascolta e visualizza il testo inviato dalla macchina client, quindi prende quel testo e lo invia all'altro programma stdout
, mentre l'altro programma si occupa stdin
essere inviato alla macchina client) o creare 2 programmi che svolgono i lavori separati (invio, ricezione e visualizzazione) e inviano i dati appropriati l'uno all'altro?
Mi dispiace se questo è stranamente formulato e chiarirò se necessario. Ho guardato exec
, execve
, fork
, ecc. Ma sono confuso sul fatto che questo sia il percorso appropriato a cui guardare o se esiste un modo più semplice che mi manca.
Qualsiasi aiuto sarebbe molto apprezzato, grazie.
MODIFICARE: In retrospettiva, ho pensato che ciò sarebbe stato molto più facile realizzato con 2 programmi separati. Uno, il server IM e gli altri, i client IM.
I client IM si connetterebbero al programma Server IM e invierebbero qualunque testo volesse al server IM. Quindi, il server IM avrebbe semplicemente registrato i dati inviati ad esso in un buffer/file con i nomi/ip dei client aggiunti al testo inviato da ciascun client e inviare quel testo (in formato di nome: testo) a Ogni client che è connesso.
Ciò rimuoverà la necessità di una complicata comunicazione tra process/programma per stdin
e stdout
, e invece, Utilizzare un semplice modo client/server di comunicare, con i programmi client che visualizzano il testo inviato dal server tramite stdout
, e usando stdin
per inviare qualsiasi testo al server.
Detto questo, sono ancora interessato a qualcuno che risponde alla mia domanda originale: per la scienza. Grazie a tutti per la lettura e, si spera, qualcuno trarrà beneficio dal mio brainstorming mentale o da qualsiasi risposta provenga dalla comunità.
Soluzione
Tuttavia, non posso programmare un modo per inviare dati alla macchina client, perché il mio programma è impegnato ad ascoltare e visualizzare il testo inviato dalla macchina client.
La stessa presa che è stata restituita da una presa di ascolto da accept()
può essere utilizzato sia per l'invio che per la ricezione di dati. Quindi la tua presa non è mai "occupata" solo perché stai leggendo da esso ... puoi scrivere sulla stessa presa.
Se hai bisogno di leggere e scrivere contemporaneamente, condividi la presa restituita accept()
attraverso due diversi thread. Poiché due diversi buffer vengono utilizzati dallo stack di networking per l'invio e la ricezione sul socket, un thread dedicato per la lettura e un altro thread dedicato per la scrittura sul socket sarà thread-safe senza l'uso di mutex.
Altri suggerimenti
Vorrei andare con fork () - Creare un processo figlio e ora hai due processi diversi che possono fare due cose diverse su due prese diverse: uno può ricevere e l'altro può inviare. Non ho ancora esperienza personale con la codifica di un client/server come questo, ma questa sarebbe la mia prima pugnalata a risolvere il tuo problema ...
Come menzionato @Bdonlan in un commento, hai sicuramente bisogno di una chiamata multiplexing come Selezionare o preferibilmente sondaggio (o Syscalls correlati come pselect
, ppoll
...). Queste chiamate multiplexing sono il primitivo per aspettare su più canali contemporaneamente (con pselect
e ppoll
in grado di aspettare atomicamente sia eventi I/O che segnali). Leggi anche il Seleziona tutorial Pagina uomo. Naturalmente, puoi attendere diversi descrittori di file e puoi attendere sia le abilità di lettura e scrittura (anche sulla stessa presa, se necessario), nello stesso select
o poll
Syscall.
Tutti i loop e i framework basati su eventi utilizzano queste chiamate multiplexing (come poll
o select
). Potresti anche usare libevent, o addirittura (in particolare quando si codifica un'applicazione di interfaccia utente grafica) un po 'di toolkit GUI come GTK o QT, che si basano su un ciclo di eventi centrali.
Non credo che avere un'applicazione multi-processo o multi-thread sia utile nel tuo caso. Hai solo bisogno di un ciclo di eventi.
Potresti anche chiedere di ottenere un SIGIO
segnale quando i dati arrivano sul tuo socket utilizzando fcntl insieme a F_SETOWN
, ma questo non è molto utile per te. Quindi spesso vuoi avere il tuo socket non bloccante.