2016-03-10 130 views
0

我正在为一项任务编写一个小型UDS服务器,并且觉得我的代码大部分存在,但是当我实际尝试运行它时,我得到的结果绝对没有。为什么我的UDS服务器不能接受连接?

该代码由一个shell脚本测试,该脚本将多个不同的测试调用发送到我的代码的主函数。传递给main的唯一东西是log文件名和UDS path,然后不同的客户端连接到服务器,这应该只是导致特定的输出日志来检查服务器代码的正确性。

我的主要功能是在这里:

int main(int argc, char * argv[]) 
{ 
    if (argc != 3) 
     return usage(argv[0]); 

    log_fd = fopen(argv[1], "a"); 

    // create a server socket 
    // domain (i.e., family) is AF_UNIX 
    // type is SOCK_STREAM 
    int listenfd = socket(AF_UNIX, SOCK_STREAM, 0);  

    socklen_t clientLength = sizeof(struct sockaddr_un); 
    struct sockaddr_un clientAddr; 
    clientAddr.sa_family = AF_UNIX; 
    strcpy(clientAddr.sun_path, argv[2]); 

    pthread_t tid; 

    // unlink the UDS path) 
    unlink(argv[2]); 

    // bind the server socket 
    bind(listenfd, (SA *)&clientAddr, clientLength);  

    // listen 
    listen(listenfd, 1024); 
    // loop to wait for connections; 
    // as each connection is accepted, 
    // launch a new thread that calls 
    // recv_log_msgs(), which receives 
    // messages and writes them to the log file 
    while(1){ 
     printf("Waiting for a connection on UDS path %s...\n", argv[2]); 
     int * clientfdp = malloc(sizeof(int)); 
     *clientfdp = accept(listenfd, (SA *) &clientAddr, &clientLength); 
     pthread_create(&tid, NULL, recv_log_msgs, clientfdp); 
    } 

    // when the loop ends, close the listening socket 
    close(listenfd);   

    // close the log file 
    fclose(log_fd); 

    return 0; 
} 

,其中用途为myloggerd <log-file-name> <UDS path>

该主函数侦听任何客户端连接,并且在接受任何客户端连接时,它会在称为recv_log_msgs的线程例程函数中创建一个新线程。我的代码是在这里:

void * recv_log_msgs(void * arg) //Thread Routine 
{ 
    // loops to receive messages from a client; 
    // when the connection is closed by the client, 
    // close the socket 
    int clientfd = *((int *)arg); 
    char buffer[1500]; 
    memset(buffer, 0, 1500); 
    int currentPos = 0; 
    int bytesRec; 
    int recvng = 1; 

    while(recvng){ 
     bytesRec = recv(clientfd, buffer, 1500-currentPos, 0); 
     currentPos += bytesRec; 
     if(buffer[currentPos - 1] == '\n') 
      recvng = 0; 
    } 

    fprintf(log_fd, "LOGGER %d %s", clientfd, buffer); 
    close(clientfd); 
    return NULL; 
} 

所以,每一个线程进入该功能时,数据被写入日志文件。如果日志文件结果正确,那么我得到100%。如果不是,那么我就失败了。

截至目前,当我测试我的解决方案时,根本没有任何反应。

我得到一个无限循环的打印,说Waiting for connection on the UDS path...,这是while在主结束。这不应该继续循环一个我已经打电话给accept并创建线程,直到该线程退出?

+0

'如果(缓冲[currentPos - 1] == '\ n' )'不能工作。无论您是否找到换行符,都取决于您获得的块大小。 – usr

+0

你是什么意思?该行取自我的教科书 编辑:但这是我的直接关注点,因为我的代码甚至没有达到该功能。 – Anonymous

+0

注意'recv'可以在第一次迭代时返回'0'和'-1'。这意味着_Undefined Behaviour_ on'buffer [currentPos - 1]' – LPs

回答

0

你是不匹配的clientAddr类型为AF_UNIX插座:必须struct sockaddr

这为我工作:

int main(int argc, char * argv[]) 
{ 
    if (argc != 3) 
     return -1; 

// log_fd = fopen(argv[1], "a"); 

    // create a server socket 
    // domain (i.e., family) is AF_UNIX 
    // type is SOCK_STREAM 
    int listenfd = socket(AF_UNIX, SOCK_STREAM, 0); 

    socklen_t clientLength = sizeof(struct sockaddr_un); 
    struct sockaddr clientAddr; 
    clientAddr.sa_family = AF_UNIX; 
    strcpy(clientAddr.sa_data, argv[2]); 

    pthread_t tid; 

    // unlink the UDS path) 
    unlink(argv[2]); 

    // bind the server socket 
    bind(listenfd, (struct sockaddr*)&clientAddr, clientLength); 

    // listen 
    listen(listenfd, 1024); 
    // loop to wait for connections; 
    // as each connection is accepted, 
    // launch a new thread that calls 
    // recv_log_msgs(), which receives 
    // messages and writes them to the log file 
    while(1){ 
     printf("Waiting for a connection on UDS path %s...\n", argv[2]); 
     int * clientfdp = malloc(sizeof(int)); 
     *clientfdp = accept(listenfd, (struct sockaddr *) &clientAddr, &clientLength); 
     pthread_create(&tid, NULL, recv_log_msgs, clientfdp); 
     free(clientfdp); 
    } 

    // when the loop ends, close the listening socket 
    close(listenfd); 

    // close the log file 
// fclose(log_fd); 

    return 0; 
} 
相关问题