2012-04-23 57 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