从socket读取字符串时,write会打印额外的字符

时间:2012-04-23 01:00:59

标签: c sockets

在以下程序中,我通过服务器进行读写。但是当执行write()时,它会输出额外的字符

// 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:$ telnet localhost 4080

输出:
尝试:: 1 ...
尝试127.0.0.1 ..
连接到localhost。
逃脱角色是'^]' Ĵ
Ĵ
DHK
9
外部主机关闭连接。

第一个“j”由用户(我)输入,第二个“j”由服务器回显。为什么我会收到“dhk”和“9”字符?

1 个答案:

答案 0 :(得分:1)

因为您忽略了收到的实际数据量,即rr而是打印整个字符串。

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

你也不应该这样做str_ptr = buff;因为这只是复制指针而不是字符串本身。 buff在堆栈上分配,因此在函数返回时可能不再有效。