gpt4 book ai didi

c++ - 基于 UNIX 的聊天室::使用 getch()、POSIX 线程存储每个字符

转载 作者:太空狗 更新时间:2023-10-29 21:45:55 24 4
gpt4 key购买 nike

全部。

我在使用 P-thread 库的基于 unix 的聊天室时遇到一个小问题和 BSD 套接字。

此时,客户端可以连接到服务器,使用他想要的用户名登录,然后选择一个房间加入。此外,可以将消息发送到服务器并将接收到的消息正确地打印到屏幕上。这都是基于文本的。

在客户端程序中,有一个主线程允许用户按下字符,然后将这些字符压入 vector ;它看起来像这样:

    std::vector<char> current_message;/*global*/
while(1)
{
c = '\0';
while(c != '\n')/*Break when enter is pressed(send message)*/
{
c = my_getch();
if((c == '\n' && current_message.size() == 0)/*Cannot send blank messages*/
|| (c == 127 && char_count == 0))
{
c = '\0';
continue;
}

if(!my_isarrow(c))
{
if(c != 127)
char_count++;
else char_count--;
printf("%c", c);
current_message.push_back(c);
}
if(current_message.size() == 250)/*Send the message if close to buf size*/
c = '\n';

}
send_message(current_message, server);
current_message.clear();/*remove characters from already-sent buffer*/
}

还有一个从服务器获取消息的线程过程 这个过程是必需的,因为我们需要允许客户端在等待来自服务器的消息的同时发送消息。

过程是这样的:

void *get_messages(void *data)
{
pthread_detach(pthread_self());/*detach the thread*/
int *sock = (int *) data;/*the thread data passed in is actually a socket
which we use to retrieve messages from server*/
while(1)
{
packet_t pkt;
read(*sock, &pkt, sizeof(packet_t));/*block until a message is received*/
for(int i = 0; i < strlen(pkt.user_name); i++)
{
if(pkt.user_name[i] == '\n')
pkt.user_name[i] = '\0';
}
pthread_mutex_lock(&lock);

chat_buffer.push_back(pkt);

for(int i = 0; i < 50; i++)
printf("\n");/*emulate clearing of terminal window*/

for(int i = 0; i < chat_buffer.size(); i++)/*chat_buffer is a global vector*/
/*that contains all received messages*/
{
for(int j = 0; j < strlen(chat_buffer[i].msg); j++)
{
if(chat_buffer[i].msg[j] == '\n')/*remove newlines(inefficient)*/
chat_buffer[i].msg[j] = '\0';
}
/*print out all received messages to the client terminal*/
printf("%s: %s\n", chat_buffer[i].user_name, chat_buffer[i].msg);

}
printf("----------------------------------------------------\n");/*some formatting for readability*/
for(int i = 0; i < current_message.size(); i++)
printf("%c", current_message[i]); *******This is the problem area*******
}

当一个客户(我)输入了一些字母并将它们插入缓冲区时,程序就会出现问题。并且,同时我们从服务器收到一条消息,屏幕“刷新”了。您可以看到 get_messages(void *) 过程中发生了什么。但是,当发生此屏幕刷新时,我不希望我(我)客户已经输入的字母消失;为了解决这个问题,我添加了一行代码,打印出当前在我的 current_message vector 中的所有字母。但是,这些字母没有打印出来(即使这里的代码清楚地说明了它们应该打印出来)注意:缓冲区中的字符是在我按下键盘上的某个键后显示的。

我的 getch() 函数的代码如下所示:

int my_getch()/*This actually didn't come from my brain*/
{
struct termios oldt, newt;
int ch;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return ch;
}

此外,my_isarrow 函数只是简单地解析传入的字符以查看它是否是箭头键。我想忽略箭头键,因为它会上下移动光标(我不想要这个。)

那么,有没有人遇到过这个问题,或者有人能在这里看到他们已经处理过的问题吗?

问候,威廉。

最佳答案

问题就在那里,因为 stdout 是一个缓冲流。

你需要在for循环之后放一个fflush(stdout);

另外用 fputc(current_message[i], stdout) 代替 printf("%c", current_message[i]) 因为这样效率更高一些:

这是您需要的增量:

  printf("----------------------------------------------------\n");/*some formatting for readability*/
for(int i = 0; i < current_message.size(); i++) {
fputc(current_message[i], stdout);
}
fflush(stdout); /* make sure that stdout is flushed, as stdout is buffered */

关于c++ - 基于 UNIX 的聊天室::使用 getch()、POSIX 线程存储每个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16472666/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com