Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在简单的客户端/服务器聊天程序中显示文本有困难(显示当前输入)-C_C_Multithreading_Networking_Network Programming - Fatal编程技术网

在简单的客户端/服务器聊天程序中显示文本有困难(显示当前输入)-C

在简单的客户端/服务器聊天程序中显示文本有困难(显示当前输入)-C,c,multithreading,networking,network-programming,C,Multithreading,Networking,Network Programming,我正在为我的网络课程编写一个聊天程序,我的网络设置非常完善 我的问题是,如果一个客户端当前正在编写一条消息,并且他从另一个客户端收到一条消息,那么他的当前输入将与收到的消息一起显示 例如,如果一个客户正在写一个信息“嗨,你好吗?”并且收到一个“好日子”的消息,而在写消息的过程中,它被显示为: 你好,祝你节日快乐 ->你是谁 其中->是用户输入消息的区域。我想做的是只显示收到的消息,并让区域->保留收到消息之前写的所有文本 请注意,当客户收到消息时,他输入的内容实际上仍然在“那里”。如果他完成了他

我正在为我的网络课程编写一个聊天程序,我的网络设置非常完善

我的问题是,如果一个客户端当前正在编写一条消息,并且他从另一个客户端收到一条消息,那么他的当前输入将与收到的消息一起显示

例如,如果一个客户正在写一个信息“嗨,你好吗?”并且收到一个“好日子”的消息,而在写消息的过程中,它被显示为:

你好,祝你节日快乐

->你是谁

其中->是用户输入消息的区域。我想做的是只显示收到的消息,并让区域->保留收到消息之前写的所有文本

请注意,当客户收到消息时,他输入的内容实际上仍然在“那里”。如果他完成了他的信息,他的完整信息将被发送

还要注意,我的客户机使用pthreads。一个线程从服务器读取消息并将其显示到用户屏幕,另一个线程从stdin读取消息并将消息发送到服务器。我确信我的问题是因为我使用pthreads,并且线程共享相同的stdin、stdout、stderr。也许这是一种误解和错误

我希望我对我的问题已经很清楚了。如果没有,对不起。请让我知道我能为你澄清什么

我开始做一些研究,发现了以下链接:

我想试着往上移动光标,但不知道这是否是最有效的方法。首先,因为我不知道如何捕获终端中等待“输入”/“发送到stdin”的信息。也许我还不知道该怎么做

我还想知道是否有办法使用/操作文件描述符来解决这个问题?也许这根本解决不了问题


谢谢你的阅读和时间。非常感谢您的帮助。

使用诸如管理文本“窗口”之类的库将比手动操作屏幕更容易。

我不是unix网络编程专家,但我非常确信,问题在于多线程本身,而不是某些标准输入/标准输出的怪癖

我在这里看到的是多个线程访问同一资源(终端会话),而没有任何同步。这不可避免地导致他们之间的竞争条件

我建议你阅读这本关于同步化问题的免费电子书,这本书对那些只稍微熟悉同步化的人特别有用:


指定一个线程作为IO线程,并通过阻塞队列(或循环缓冲区)将要显示的消息发送给该线程。C有吗?(我目前使用Java)。

问题涉及线程。您的解决方案是要么使用一个显示器并阻止传入消息,直到用户完成当前输入,要么使用两个“窗口”。许多对话程序有两个窗口:一个用于输入数据(或当前对话),另一个用于生成下一条消息


标准C语言没有线程、窗口或光标定位功能。您只需使用特定于平台的功能即可。由于您没有指定平台,因此您必须自己查找这些平台。

默认情况下,用户输入由终端本身处理,因此,如果您需要实时更新,仅使用互斥锁是不会切断的。如果您想要线路输入模式解决方案,您可以记录传入消息,并在每次发送消息时以及在读取下一条消息之前提交它们

否则,你最好按照建议使用诅咒。启用scrollok(3x)的窗口可以像终端一样轻松地使用waddstr(3x)和wgetnstr(3x),如果使用类似IRC的UI,则无需对其进行微观管理


请注意,使用curses并不意味着您不必在curses函数周围使用互斥体。否则,当您不太期望时,屏幕将充满垃圾。

使用互斥锁防止另一个线程同时写入输出。这是最好的方法。您希望保留一个表示所接收文本结尾位置的变量,该变量将告诉您在何处插入新消息。顺序应该是这样的:1)停止响应用户按键2)抓取现有用户输入3)清除用户输入4)插入新消息5)消息结尾处的记录6)重新插入用户输入7)在插入消息时对接收到的任何缓冲输入进行操作