在简单的客户端/服务器聊天程序中,显示文本遇到困难(当前输入被显示)- C
在简单的客户端/服务器聊天程序中,显示文本遇到困难(当前输入被显示)- C
我正在为我的网络课程编写一个聊天程序,网络设置一切都很完美。
我的问题是,如果一个客户端正在写消息,并且他接收到来自另一个客户端的消息,那么他当前的输入将与接收到的消息一起显示。
例如,如果一个客户端正在写一条消息“你好,你好吗?”并在写消息的过程中接收到一条消息“祝你好运!”,则显示为:
你好,你好祝你好运!
->你好吗?
其中->是用户输入消息的区域。我希望发生的是仅显示接收到的消息,并保留在收到消息之前写入的所有文本。
请注意,当客户端接收到消息时,他正在输入的内容仍然存在。如果他完成了消息,他将发送完整的消息。
还请注意,我的客户端使用pthread。一个线程用于从服务器读取消息并将其显示到用户屏幕上,另一个线程用于从stdin读取并将消息发送到服务器。我相信我的问题是由于我正在使用pthread,而这些线程共享相同的stdin、stdout、stderr。也许这是一个误解和错误吗?
我希望我已经清楚地表达了我的问题。如果没有,请告诉我需要澄清什么。
我开始做一些研究,找到了这些链接:
我考虑尝试上移行并移动光标等操作,但不知道是否是最有效的方法。首先,因为我不知道如何捕获在终端中等待“输入”/发送到stdin的信息。也许我只是还没有找到如何做到这一点。
另外,我想知道是否有一种方法可以通过操作文件描述符来解决这个问题?也许这甚至不能解决它?
感谢您的阅读和时间。我非常感谢您的帮助。
这个问题的原因是多线程访问同一资源(终端会话)而没有进行同步,导致它们之间出现了竞争条件。为了解决这个问题,可以阅读这本关于同步问题的免费电子书,特别适用于对同步只有一些了解的人:http://www.greenteapress.com/semaphores/
在简单的客户端/服务器聊天程序中,显示文本存在困难(当前输入被显示)。出现这个问题的原因是没有指定一个线程作为IO线程,并且通过一个阻塞队列(或循环缓冲区)将要显示的消息发送到该线程。解决方法是在C中使用类似的机制,如使用线程和队列来实现。下面是一个示例代码:
#include#include #include #define MAX_MESSAGES 100 #define MESSAGE_LENGTH 100 // Define a circular buffer typedef struct { char messages[MAX_MESSAGES][MESSAGE_LENGTH]; int head; int tail; int count; } CircularBuffer; // Initialize the circular buffer void initCircularBuffer(CircularBuffer* buffer) { buffer->head = 0; buffer->tail = 0; buffer->count = 0; } // Add a message to the circular buffer void addMessage(CircularBuffer* buffer, const char* message) { strncpy(buffer->messages[buffer->tail], message, MESSAGE_LENGTH); buffer->tail = (buffer->tail + 1) % MAX_MESSAGES; buffer->count++; } // Get the next message from the circular buffer void getNextMessage(CircularBuffer* buffer, char* message) { strncpy(message, buffer->messages[buffer->head], MESSAGE_LENGTH); buffer->head = (buffer->head + 1) % MAX_MESSAGES; buffer->count--; } // IO thread function void* ioThread(void* arg) { CircularBuffer* buffer = (CircularBuffer*)arg; char message[MESSAGE_LENGTH]; while (1) { // Get the next message from the buffer getNextMessage(buffer, message); // Display the message printf("%s\n", message); } return NULL; } int main() { // Create a circular buffer CircularBuffer buffer; initCircularBuffer(&buffer); // Create the IO thread pthread_t thread; pthread_create(&thread, NULL, ioThread, (void*)&buffer); // Main thread char input[MESSAGE_LENGTH]; while (1) { // Read user input fgets(input, MESSAGE_LENGTH, stdin); // Add the input to the buffer addMessage(&buffer, input); } return 0; }
上面的代码创建了一个循环缓冲区,通过使用线程和阻塞队列的概念,将要显示的消息从主线程发送到IO线程进行显示。这样可以避免当前输入被显示的问题。
(Difficulties displaying the text in simple client/server chat program (current input gets displayed) - C)这个问题的出现的原因是在简单的客户端/服务器聊天程序中,文本无法正确显示。解决方法是使用一个库(如curses)来管理文本“窗口”,而不是手动操作屏幕。
解决方法如下:首先,需要保持一个变量来表示接收到的文本的末尾位置,这将告诉你在哪里插入新的消息。操作的顺序应该是:1)停止响应用户的按键输入;2)获取现有的用户输入;3)清除用户输入;4)插入新的消息;5)记录该消息的末尾位置;6)重新插入用户输入;7)处理在插入消息时接收到的任何缓冲输入。