c++ - UNIX-based chatroom::storing each character using getch(), POSIX threads -
all.
i having small issue unix-based chatroom utilizes p-thread library , bsd sockets.
at point, client able connect server, login desired username, , select room join. also, messages can sent server , received messages printed screen correctly. text based.
in client program, there main thread allows user press characters pushed onto vector; looks this:
std::vector<char> current_message;/*global*/ while(1) { c = '\0'; while(c != '\n')/*break when enter 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 message if close buf size*/ c = '\n'; } send_message(current_message, server); current_message.clear();/*remove characters already-sent buffer*/ }
there thread procedure retrieves messages server procedure needed because need allow client send messages,concurrently, while waiting messages server.
the procedure looks this:
void *get_messages(void *data) { pthread_detach(pthread_self());/*detach thread*/ int *sock = (int *) data;/*the thread data passed in socket use retrieve messages server*/ while(1) { packet_t pkt; read(*sock, &pkt, sizeof(packet_t));/*block until message received*/ for(int = 0; < 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 = 0; < 50; i++) printf("\n");/*emulate clearing of terminal window*/ for(int = 0; < chat_buffer.size(); i++)/*chat_buffer global vector*/ /*that contains 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 received messages client terminal*/ printf("%s: %s\n", chat_buffer[i].user_name, chat_buffer[i].msg); } printf("----------------------------------------------------\n");/*some formatting readability*/ for(int = 0; < current_message.size(); i++) printf("%c", current_message[i]); *******this problem area******* }
the problem in program occurs when 1 client (me) has typed in letters , pushed onto buffer. and, @ same time received message server , screen "refreshed." can see happening in get_messages(void *) procedure. however, when screen refreshing occurs, don't want (me) client's already-typed-in letters disappear; in order fix added line of code prints out letters in current_message vector. however, letters not printed out (even when code here says should be) note: characters in buffer show after press key on keyboard.
the code getch() function looks this:
int my_getch()/*this didn't come 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; }
also, my_isarrow function parses incoming characters see if arrow key. want ignore arrow keys because moves cursor , down(i dont want this.)
so, has experienced problem or can see problem here have dealt?
regards, william.
the problem there because stdout buffered stream.
you need put fflush(stdout) after loop;
an aside fputc(current_message[i], stdout) instead of printf("%c", current_message[i]) that's bit more efficient:
here delta need:
printf("----------------------------------------------------\n");/*some formatting readability*/ for(int = 0; < current_message.size(); i++) { fputc(current_message[i], stdout); } fflush(stdout); /* make sure stdout flushed, stdout buffered */
Comments
Post a Comment