2013-05-09 1 views
3

모두를 사용하여 각 문자 저장.UNIX 기반 chatroom :: getch(), POSIX 스레드

나는 P 스레드 라이브러리 과 BSD 소켓을 사용하는 유닉스 기반 chatroom에 약간의 문제가있다.

이 시점에서 클라이언트는 원하는 사용자 이름으로 로그인하고 서버에 연결할 수 있으며 회의실을 선택합니다. 또한 메시지를 서버로 전송할 수 있으며 수신 된 메시지가 화면에 올바르게 인쇄됩니다. 모든 텍스트 기반입니다.

클라이언트 프로그램에는 사용자가 문자를 눌러 벡터에 푸시 할 수있는 주 스레드가 있습니다. 그것은 다음과 같습니다 그는의 메시지를 기다리는 동안

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 벡터에있는 모든 문자를 출력하는 코드 행을 추가했습니다. 그러나 글자는 인쇄되지 않습니다 (여기에 코드가 명확해야 함에도 불구하고) 참고 : 키보드의 일부 키를 누르면 버퍼의 문자가 표시됩니다.

내 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 기능은 단순히 화살표 키 있는지 확인하기 위해 수신 문자를 구문 분석합니다. 나는 커서를 위아래로 움직이기 때문에 화살표 키를 무시하고 싶다. (나는 이것을 원하지 않는다.)

그렇다면이 문제를 경험 한 사람이 있습니까? 아니면 누구도 이미 처리 한 문제를 볼 수 있습니까?

감사합니다, 윌리엄.

답변

2

stdout이 버퍼링 된 스트림이므로 문제가 있습니다.

for 루프 뒤에 fflush (stdout)를 넣어야합니다.

여담 fputc (current_message [I], 표준 출력) 대신의 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 */ 
+0

아메드, 감사합니다. –

+1

그것이 실제 문제인지 알려주세요 ... –

+0

예. 이제 작동합니다. :) –