2012-04-23 58 views
-1

在下面的程序中,我通過服務器讀取和寫入。但是,當執行寫(),它打印出多餘的字符從插座讀取字符串時,寫入打印額外字符

// this a server program 
#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <unistd.h>    // for ssize_t data type 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <sys/un.h> 
#include <arpa/inet.h> 
#include <errno.h> 
#include <wait.h> 

#define LISTENQ  (24) /* Backlog for listen() */ 
#define MAXBUFFSIZE 12 

// Read in characters. Increase memory if we run out of space. 
char *stdin_line(int conn) 
{ 
    int rr=0, size=0, cap = MAXBUFFSIZE; 
    char *str_ptr;//, oc; 
    char buff[MAXBUFFSIZE]; 

    // allocate some memory for the pointer first 
    str_ptr = (char *) malloc(cap * sizeof(char)); 
    assert(str_ptr != NULL); 
    // start reading from socket 
    rr=read(conn,buff,MAXBUFFSIZE)) > 0) 
     if(rr > 0){ 
    str_ptr = buff; 
    size = MAXBUFFSIZE; 
    } 
    if(rr == -1) printf("Error (stdin_line): %s/n",strerror(errno)); 

    return str_ptr; 
} 


void daemonize(void){ 
    pid_t pid, sid=0; 
    // fork off process 
    pid = fork(); 
    // failure 
    if(pid < 0){ 
    printf("Error (fork<0): %s\n",strerror(errno)); 
    exit(1); 
    } 
    // exit parent process 
    if(pid > 0){ 
    printf("Error (fork>0): %s\n",strerror(errno)); 
    exit(0); 
    } 
    // change file mode mask 
    umask(0); 

// open log file for daemon debug information. OR as per requirements of hw4 

    // create new Session ID for child process 
    setsid(); 
    if(sid < 0){ 
    printf("Error (setsid<0): %s\n",strerror(errno)); 
    exit(1); 
    } 
    // exit parent process 
    if(sid > 0){ 
    printf("Error (setsid>0): %s\n",strerror(errno)); 
    exit(0); 
    } 

    // change working directory to safe directory (one which is always there) 
    if(chdir("/") < 0){ 
    printf("Error (chdir): %s\n",strerror(errno)); 
    exit(1); 
    } 

} 


int main(void) { 

    int lstn_sock, conn_sock; 
    struct sockaddr_in my_serv; 
    short int pnum = 4080; 
    ssize_t wnum; 
    char *rstr=NULL; 

    // create listening socket 
    if((lstn_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 
    printf("Error (socket): %s\n",strerror(errno)); 
    exit(1); 
    } 

    // initialize socket address 
    memset(&my_serv, 0, sizeof(my_serv)); 
    my_serv.sin_family = AF_INET; 
    my_serv.sin_addr.s_addr = INADDR_ANY; 
    my_serv.sin_port = htons(pnum); 

    // associate address with socket. 
    if(bind(lstn_sock, (struct sockaddr *) &my_serv, sizeof(my_serv)) < 0){ 
    printf("Error (bind): %s\n",strerror(errno)); 
    exit(1); 
    } 
    // start listening to socket 
    if(listen(lstn_sock, LISTENQ) < 0){ 
    printf("Error (listen): %s\n",strerror(errno)); 
    exit(1); 
    } 
    // make it a daemon 
    daemonize(); 

    // work in the background 
    while(1){ 
    // retrieve connect request and connect 
    if((conn_sock = accept(lstn_sock, NULL, NULL)) < 0){ 
     printf("Error (accept): %s\n",strerror(errno)); 
     exit(1); 
    } 

    rstr = stdin_line(conn_sock); 

    if((wnum=write(conn_sock,rstr,strlen(rstr))) <= 0){ 
     printf("Error (write: rstr): %s\n",strerror(errno)); 
     exit(1); 
    } 

    // close connected socket 
    if(close(conn_sock) < 0){ 
     printf("Error (close): %s\n",strerror(errno)); 
     exit(1); 
    } 
    } 


return 0; 

} 

@ubuntu:$ ./my_code
@ubuntu:$遠程登錄本地主機4080

輸出:
嘗試:: 1。 ..
嘗試127.0.0.1 ..
連接到本地主機。
轉義字符是'^]'。
Ĵ
Ĵ
DHK
連接國外主機關閉。

第一個「j」由用戶(我)輸入,第二個「j」由服務器迴應。爲什麼我會得到「dhk」和「9」字符?

回答

1

由於您忽略了您收到的實際數據量,即rr,而是打印整個字符串。

rr=read(conn,buff,MAXBUFFSIZE)) > 0) 
    if(rr > 0){ 
str_ptr = buff; 
size = MAXBUFFSIZE; 
} 

你也應該這樣做str_ptr = buff;,因爲這只是複製了指針,而不是字符串本身。 buff分配在堆棧上,所以函數返回時可能不再有效。

+0

謝謝@ Tibor。實際上,我打算一次從read()讀取一個字符,然後在最後分配一個空字符來終止整個字符串。希望它有效! – jdek 2012-04-23 01:24:59