字符数组不会在我的服务器中打印

时间:2011-11-07 01:36:12

标签: c++ c network-programming ncurses

我的服务器打印发送的内容有问题。我知道正在收到数据,因为它会将数据广播回所有客户端。

#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 函数中。

提前致谢。

1 个答案:

答案 0 :(得分:1)

telnet在每一行的末尾发送"\r\n"。如果不删除这些字符,则每行打印都会立即被覆盖。

我认为在服务器中使用ncurses是个坏主意。通常您希望将日志保存到文件,如果您使用ncurses,这将非常困难。而且,你会遇到这样的问题,因为你无法确切地说出你的程序正在输出什么。