在简单的客户端/服务器聊天程序中显示文本有困难(显示当前输入)- C
我正在为我的网络课程编写一个聊天程序,并且我完美地完成了所有网络设置。
我的问题是,如果客户端当前正在编写消息并且他收到来自不同客户端的消息,那么他当前的输入将与接收到的消息一起显示。
例如,如果客户正在写一条消息“嗨,你好吗?”并收到一条消息“祝你有美好的一天!”在编写消息的过程中,它显示为:
你好,祝你有美好的一天!
->你是谁?
哪里->是用户输入消息的区域。我想要发生的事情是只显示收到的消息并拥有区域 ->保留在收到消息之前写入的所有先前文本。
请注意,当客户收到消息时,他输入的内容实际上仍然“在那里”。如果他完成了他的消息,他的完整消息将被发送。
另请注意,我的客户端使用 pthreads。一个线程从服务器读取消息并将其显示到用户屏幕,另一个线程从标准输入读取消息并将消息发送到服务器。我确实相信我的问题出现是因为我使用 pthreads 并且线程共享相同的 stdin、stdout、stderr。也许这是一种误解和错误?
我希望我已经清楚地了解了我的问题。如果没有,抱歉。请让我知道我可以为您澄清什么。
我开始做一些研究并发现了这些链接:
我正在考虑尝试向上移动并移动光标周围的东西,但不知道这是否是最有效的方法。首先,因为我不知道如何捕获终端中等待“输入”/发送到标准输入的信息。也许我只是还没找到如何做到这一点。
我也想知道是否有一种方法可以工作/操作文件描述符来解决问题?也许这根本就不能解决问题?
感谢您的阅读和您的时间。我感谢你的所有帮助。
I am writing a chat program for my networking class and I have all the networking setup perfectly.
My problem is if a client is currently writing a message and he receives a message from a different client then his current input gets displayed with the received message.
For example if a client is writing a message "Hi there how are you?" and receives a message "Good day to you!" while in the middle of writing their message it gets displayed as:
Hi there hoGood day to you!
->w are you?
Where -> is the area for the user to type in the message. What I would like to happen is to just display the message received and have the area -> retain all the previous text that was written before the message was received.
Please make note that what the client is typing in is still in fact "there" when he receives a message. If he completes his message his full message will be sent.
Also note that my client uses pthreads. One thread to read messages from the server and display them to the users screen and one thread to read from stdin and send the messages to the server. I do believe that my problem is arising because I am using pthreads and the threads share the same stdin, stdout, stderr. Maybe this is a misconception and wrong?
I hope I have been clear on my problem. If not, sorry. Please let me know what I can clarify for you.
I started doing some research and came upon these links:
I was thinking about trying to go up lines and move the cursors around and stuff, but don't know if that is the most effective way to do so. Firstly because I don't know how to capture the information that is in the terminal waiting to "entered"/sent to stdin. Maybe I just haven't found out how to do that.
Also I was wondering if there was a way to work/manipulate file descriptors to solve the problem? Maybe that wouldn't even solve it?
Thanks for reading and your time. I appreciate all your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用诸如 curses 之类的库来管理文本“窗口”会比尝试用手操作屏幕。
Using a library such as curses to manage text 'windows' will be easier than trying to manipulate the screen by hand.
我不是 unix 网络编程方面的专家,但我非常确信问题出在多线程本身,而不是某些 stdin/stdout 怪癖。
我在这里看到的是多个线程访问同一资源(终端会话)而没有任何同步。这不可避免地导致它们之间出现竞争条件。
我建议您阅读这本关于同步问题的免费电子书,这对于那些对同步稍有了解的人特别有帮助:
http://www.greenteapress.com/semaphores/
I am not an expert in unix network programming, but I am pretty much convinced that the problem is with multithreading itself rather than some stdin/stdout quirks.
What I see here is multiple threads accessing the same resource (terminal session) without any synchronization. This inevitably leads to race conditions between them.
I would recommend you to read this free e-book on sychronization problems, which is especially helpful for those who are only slightly familliar with sychronization:
http://www.greenteapress.com/semaphores/
指定一个线程作为IO线程,并通过阻塞队列(或循环缓冲区)将要显示的消息发送给该线程。 C有那些吗? (我目前使用Java)。
Designate a thread as the IO thread and sent the messages to be displayed to that thread through a blocking queue (or circular buffer). Does C have those? (I use Java currently).
该问题涉及线程。您的解决方案是使用一个显示器并阻止传入消息,直到用户完成当前输入,或者使用两个“窗口”。许多对话程序有两个窗口:一个用于传入数据(或当前对话),另一个用于构建下一条消息。
标准 C 语言没有线程、窗口或光标定位的功能。您只需要使用特定于平台的功能即可。由于您没有指定平台,因此您必须自己查找这些平台。
The problem involves threading. Your solutions are to either use one display and block the incoming message until the user finishes with the current input or use two "windows". Many conversation programs have two windows: one for incoming data (or the current conversation) and another to build the next message.
The standard C language does not have facilities for threading, windowing or cursor positioning. You'll just have to use platform specific features. Since you didn't specify your platform, you will have to look these up yourself.
默认情况下,用户输入由终端本身处理,因此如果您想要实时更新,单独的互斥体不会削减它。如果您想要一个行输入模式解决方案,您可以记录传入的消息,并在每次发送消息时和读取下一条消息之前提交它们。
否则,最好的选择是按照建议使用诅咒。使用 waddstr(3x) 和 wgetnstr(3x) 可以像终端一样使用启用了 rollok(3x) 的窗口,如果您使用类似 IRC 的 UI,则无需进行微观管理。
请注意,使用curses并不意味着您不必在curses函数周围使用互斥体。否则,当你不经意间,屏幕就会变得充满垃圾。
By default user input is handled by the terminal itself, so a mutex alone wouldn't cut it if you want real-time updates. If you wanted a line-input mode solution you could log incoming messages and commit them every time a message is sent and before the next one is read.
Else, your best bet would be using curses as suggested. A scrollok(3x) enabled window can be used like a terminal easily using waddstr(3x) and wgetnstr(3x), no need to micromanage that if you use an IRC-like UI.
Note that using curses doesn't mean you don't have to use a mutex around your curses functions. Else, when you less expect it the screen will become full of garbage.