2011-11-07 21 views
0

我遇到問題,我的服務器正在打印發送給它的內容。我知道數據正在被接收,因爲它會將其廣播回所有客戶端。字符數組不會在我的服務器中打印

#include <iostream> 
#include <string> 
#include <string.h> 
#include <errno.h> 
#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <ncurses.h> 
#include <vector> 

#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 

#define MAX_CONNECTIONS 10 
#define MAX_SRSIZE 500 

using namespace std; 

struct bcpackage{ 
    string * message; 
}; 
struct clientval{ 
    int fd; 
}; 

vector<int> file_descriptors; 
WINDOW * console, * input; 

void * handleClient(void * arg); 
void * broadcast(void * arg); 
void wprintr(WINDOW * win, const char * message); 

int main(int argc, char **argv) 
{ 
    int myfd, * status; 
    status = new int(); 
    struct addrinfo myaddrinfo, *res; 

/****************SETUP NCURSES UI******************/ 
    initscr(); 
    int y, x; 
    getmaxyx(stdscr, y, x); 
    console = subwin(stdscr,y - 1, x, 0, 0); 
    input = subwin(stdscr,1,x,y-1,0); 
    wrefresh(console); 
    wprintr(input,">"); 
/**************************************************/ 
    string port = "25544"; 
    memset(&myaddrinfo, 0, sizeof(myaddrinfo)); 
    myaddrinfo.ai_family = AF_UNSPEC; 
    myaddrinfo.ai_socktype = SOCK_STREAM; 
    myaddrinfo.ai_flags = AI_PASSIVE;//Specifies that your socket will be a passive  socket that waits for connections 
    wprintr(console,"Starting Server"); 
    int aistat = getaddrinfo(NULL, "25544", &myaddrinfo, &res); 
    if(aistat == 0){ 
     wprintr(console,"Host Information Retrieved"); 
    } 
    else{ 
     //string message = "Error: "; 
     //message+=gai_strerror(aistat); 
     wprintr(console, gai_strerror(aistat)); 
     endwin(); 
     exit(1); 
    } 
//We now have our address now we create a socket 
    myfd = socket(res->ai_family, res->ai_socktype,res->ai_protocol); 
    if(myfd==-1){ 
     wprintr(console, "Socket Creation Failed"); 
     getch(); 
     endwin(); 
     exit(2); 
    } 
//If all went well, we now have a socket for our server 
//we will now use the bind() function to bind our socket 
//to our program. I think that is what it does at least. 
    *status = bind(myfd, res->ai_addr, res->ai_addrlen); 
    //wprintw(console, "Status: %d\n", *status); 
    if((*status) < 0){ 
     wprintr(console, "Bind failed"); 
     getch(); 
     endwin(); 
     exit(3); 
    } 
    else{ 
     wprintr(console, "Bind success"); 
    } 
    //Now that we are bound, we need to listen on the socket 
    *status = listen(myfd, MAX_CONNECTIONS); 
    if(status>=0){ 
     wprintr(console, "Listening on socket"); 
    } 
    else{ 
     wprintr(console, "Listen failed"); 
     getch(); 
     endwin(); 
     exit(4); 
    } 

//Everything is setup now we send the server into a loop that will pass 
//each client to a new pthread. 
    while(true){ 

     int *clientfd = new int(); 
     pthread_t * cliPID = new pthread_t(); 
     struct sockaddr_in * cliaddr = new struct sockaddr_in(); 
     socklen_t *clilen = new socklen_t(); 
     *clilen = sizeof(*cliaddr); 
     *clientfd = accept(myfd, (struct sockaddr *)cliaddr, clilen); 
     file_descriptors.push_back(*clientfd); 
     pthread_create(cliPID, NULL, handleClient, clientfd); 

    } 
    wprintr(console, "Now Exiting"); 
    getch(); 
    endwin(); 
    return 0; 
} 

void * handleClient(void * arg){//Reads and writes to the functions 
    int filedesc = *((int *)arg); 
    char buffer[MAX_SRSIZE]; 
    char * buf = buffer; 
    memset(&buffer, 0, sizeof(buffer)); 
    while(!read(filedesc, buf, sizeof(buffer))<=0){ 
     if(strcmp(buf, "")!=0){ 
      wprintr(console, buffer);//<- I think this is the problem Idk why though. 
      broadcast(&buffer); 
     } 
     memset(&buffer, 0, sizeof(buffer)); 
    } 
    wprintr(console, "Client Exited"); 
    int fdremove = -1; 
    for(int i = 0; i < file_descriptors.size(); i++){ 
     if(file_descriptors.at(i)==filedesc){ 
      file_descriptors.erase(file_descriptors.begin()+i); 
      wprintr(console, "File Descriptor Removed"); 
     } 
    } 
    pthread_exit(NULL); 

} 

void * broadcast(void * arg){ 
    char * message = (char *)arg; 
    int num_fds = file_descriptors.size(); 
    for(int i = 0; i < num_fds; i++){ 
     write(file_descriptors.at(i), message, MAX_SRSIZE); 
    } 

} 
void wprintr(WINDOW * win, const char * message){ 
    wprintw(win, message); 
    wprintw(win, "\n"); 
    wrefresh(win); 
} 

這是爲Linux編寫的,需要-lpthread和-lncurses來編譯。當你運行服務器時,你可以telnet到它來測試它。我知道正在收到數據,因爲它正在被廣播回所有的客戶端,但是收到的數據沒有被打印在服務器的屏幕上。我認爲這可能是一個與ncurses的問題,但我不知道。我相信問題在於我的handleClient函數。

在此先感謝。

+0

認真嗎?你發現**沒辦法**來縮小問題的範圍?請儘量做出一個*最小的完整示例*,它可以證明您的問題。 –

+0

對不起。我指定了我認爲問題出在哪裏。我只是給了所有的代碼,因爲我不確定爲什麼有問題。 –

回答

1

telnet在每行的末尾發送"\r\n"。如果您不刪除這些字符,您打印的每一行都會立即被覆蓋。

我認爲在服務器中使用ncurses是個壞主意。通常你想把日誌保存到一個文件中,如果你使用ncurses,這將非常困難。而且,你會遇到這樣的問題,因爲你無法確切知道你的程序在輸出什麼。

+0

我想讓它成爲一個命令行應用程序。你會建議我使用什麼? –

+0

@HudsonWorden簡單的'printtf's​​或'cout'流應該足夠用於服務器。 –