В C на Linux, как мне использовать 2 программы, последняя отправляет текстовые данные в первую, отображаемую с помощью stdout? - PullRequest
0 голосов
/ 15 января 2012

Я пишу простую программу для обмена мгновенными сообщениями на C в Linux .

Сейчас у меня есть программа, которая связывает сокет с портом на локальной машине, и прослушивает текстовые данные, отправленные другой программой, подключенной к IP-адресу моей локальной машины. и порт.

Хорошо, я могу заставить этого клиента отправлять текстовые данные в мою программу, и отображать их, используя stdout, на моем локальном компьютере; однако я не могу запрограммировать способ отправки данных обратно на клиентский компьютер , поскольку моя программа занята прослушиванием и отображением текста, отправленного клиентским компьютером.

Как мне поступить с созданием нового процесса (который прослушивает и отображает текст, отправленный ему клиентским компьютером, затем берет этот текст и отправляет его на stdout другой программы, в то время как другая программа заботится о stdin отправляется на клиентский компьютер) или создать 2 программы, которые выполняют отдельные задания (отправка, получение и отображение) и отправляют соответствующие данные друг другу?

Извините, если это странно сформулировано, и я уточню, если это будет необходимо. Я изучил exec, execve, fork и т. Д., Но смущен тем, является ли это подходящим путем для поиска, или есть более простой способ, который я пропускаю.

Любая помощь будет принята с благодарностью, спасибо.

РЕДАКТИРОВАТЬ : Оглядываясь назад, я подумал, что это будет гораздо проще сделать с двумя отдельными программами. Один - IM-сервер, остальные - IM-клиенты.

Клиенты IM будут подключаться к программе IM-сервера и отправлять любой текст, который они хотят, на IM-сервер. Затем IM-сервер просто записывает отправленные ему данные в буфер / файл с именами / ip клиентов, добавленными к тексту, отправляемому ему каждым клиентом, и отправляет этот текст (в формате name: text) на каждый клиент, который подключен.

Это устранит необходимость в сложном межпроцессном / программном взаимодействии для stdin и stdout, и вместо этого использует простой клиент / серверный способ связи , когда клиентские программы отображают текст отправляется на сервер с помощью stdout и с помощью stdin отправляет любой текст на сервер.

С учетом сказанного я все еще заинтересован в том, чтобы кто-нибудь ответил на мой первоначальный вопрос: для науки. Спасибо всем за чтение, и, надеюсь, кто-то извлечет пользу из моего мозгового штурма или любых ответов сообщества.

Ответы [ 3 ]

3 голосов
/ 15 января 2012

однако я не могу запрограммировать способ отправки данных обратно на клиентский компьютер, поскольку моя программа занята прослушиванием и отображением текста, отправленного клиентским компьютером.

Тот же сокетaccept(), который был возвращен из прослушивающего сокета, может использоваться как для отправки, так и для получения данных.Таким образом, ваш сокет никогда не "занят" только потому, что вы читаете из него ... вы можете записывать обратно в один и тот же сокет.

Если вам нужно одновременно выполнять чтение и запись, то поделитесь сокетом, возвращенным изaccept() в двух разных потоках.Поскольку сетевой стек для отправки и получения в сокете использует два разных буфера, выделенный поток для чтения и другой выделенный поток для записи в сокет будут поточно-ориентированными без использования мьютексов.

0 голосов
/ 15 января 2012

Как отметил @bdonlan в комментарии, вам определенно необходим мультиплексный вызов, например select или предпочтительно poll (или связанные системные вызовы, такие как pselect, ppoll ...),Эти мультиплексные вызовы являются примитивами для ожидания сразу по нескольким каналам (с pselect и ppoll, способными атомарно ожидать как событий ввода / вывода, так и сигналов).Прочитайте также справочную страницу select man.Конечно, вы можете подождать несколько файловых дескрипторов, и вы можете подождать как чтения, так и записи (даже на одном сокете, если необходимо) в одном и том же select или poll syscall.

Все основанные на событиях циклы и структуры используют эти вызовы мультиплексирования (как poll или select).Вы также можете использовать libevent или даже (особенно при кодировании приложения с графическим интерфейсом пользователя) некоторый инструментарий GUI, такой как Gtk или Qt, которые основаны на центральном цикле событий.

НадеюсьНе думаю, что в вашем случае полезно иметь многопроцессорное или многопоточное приложение.Вам просто нужен некоторый цикл обработки событий.

Вы также можете попросить получить сигнал SIGIO, когда данные поступают на ваш сокет, используя fcntl с F_SETOWN, но это не очень полезно длявы.Тогда вы часто хотите, чтобы ваш сокет был неблокирующим.

0 голосов
/ 15 января 2012

Я бы пошел с fork () - создайте дочерний процесс, и теперь у вас есть два разных процесса, которые могут делать две разные вещи на двух разных сокетах - один может получать, а другой - отправлять. У меня пока нет личного опыта кодирования клиента / сервера, но это был бы мой первый удар в решении вашей проблемы ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...