Трудности с отображением текста в простой клиент-серверной программе чата (отображается текущий ввод) - C - PullRequest
3 голосов
/ 20 января 2010

Я пишу программу чата для своего сетевого класса, и у меня все настройки сети отлично.

Моя проблема в том, что если клиент в данный момент пишет сообщение и получает сообщение от другого клиента, тогда его текущий ввод отображается вместе с полученным сообщением.

Например, если клиент пишет сообщение "Привет, как дела?" и получает сообщение "Добрый день!" в то время как в середине написания их сообщения оно отображается как:

Привет, добрый день!

-> а ты?

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

Пожалуйста, обратите внимание, что то, что печатает клиент, все еще на самом деле "там", когда он получает сообщение. Если он завершит свое сообщение, его полное сообщение будет отправлено.

Также обратите внимание, что мой клиент использует pthreads. Один поток для чтения сообщений с сервера и отображения их на экране пользователя, и один поток для чтения со стандартного ввода и отправки сообщений на сервер. Я действительно считаю, что моя проблема возникает из-за того, что я использую pthreads и потоки используют один и тот же stdin, stdout, stderr. Может быть, это заблуждение и неправильно?

Надеюсь, я ясно понял свою проблему. Если нет, извините. Пожалуйста, дайте мне знать, что я могу уточнить для вас.

Я начал проводить исследования и наткнулся на следующие ссылки:

Я думал о попытке подняться вверх по линиям и перемещать курсоры и прочее, но не знаю, является ли это наиболее эффективным способом сделать это. Во-первых, потому что я не знаю, как перехватить информацию, которая находится в терминале, ожидая, когда он «введен» / отправлен на стандартный ввод. Может быть, я просто не узнал, как это сделать.

Также мне было интересно, есть ли способ работать / манипулировать файловыми дескрипторами для решения проблемы? Может быть, это даже не решит?

Спасибо за чтение и ваше время. Я ценю вашу помощь.

Ответы [ 5 ]

4 голосов
/ 20 января 2010

Использование библиотеки, такой как curses , для управления текстовыми «окнами» будет проще, чем пытаться манипулировать экраном вручную.

1 голос
/ 20 января 2010

Я не специалист по сетевому программированию в Unix, но я почти уверен, что проблема заключается в многопоточности, а не в некоторых причудах stdin / stdout.

Здесь я вижу, что несколько потоков обращаются к одномуресурс (терминальная сессия) без какой-либо синхронизации.Это неизбежно приводит к гонкам между ними.

Я бы порекомендовал вам прочитать эту бесплатную электронную книгу по проблемам синхронизации, которая особенно полезна для тех, кто немного знаком с синхронизацией:

http://www.greenteapress.com/semaphores/

0 голосов
/ 20 января 2010

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

Иначе, ваша лучшая ставка будет использовать проклятия, как предложено. Окно с поддержкой scrollok (3x) можно легко использовать как терминал, используя waddstr (3x) и wgetnstr (3x), не нужно микроуправлять, если вы используете IRC-подобный интерфейс.

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

0 голосов
/ 20 января 2010

Проблема связана с многопоточностью. Ваши решения состоят в том, чтобы либо использовать один дисплей и заблокировать входящее сообщение до тех пор, пока пользователь не завершит текущий ввод, либо использовать два «окна». Многие диалоговые программы имеют два окна: одно для входящих данных (или текущего разговора) и другое для создания следующего сообщения.

Стандартный язык C не имеет возможностей для многопоточности, создания окон или позиционирования курсора. Вам просто нужно использовать специальные функции платформы. Поскольку вы не указали свою платформу, вам придется искать их самостоятельно.

0 голосов
/ 20 января 2010

Обозначает поток как поток ввода-вывода и отправляет сообщения, которые будут отображаться этому потоку, через очередь блокировки (или кольцевой буфер). Есть ли у C такие? (Я использую Java в настоящее время).

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