emdotzed
emdotzed

Reputation: 5

C Socket client prints out a strange output

I'm trying to send a .txt file to a Linux socket client from a Linux server client (I use the loopback interface). I tried to a send a string, i.e. "OK", and everything worked fine, but when I try to send a file, the client prints out a strange output. Obviously I've done all the previous steps like socket, connect, accept, listen etc.

This is the server-side code:

printf("Sending file\n);
if ((fp=fopen(filename, "r"))!=NULL){
   while ( (nbytes = fread(sendline, sizeof(char), 512, fp) > 0)){
        printf("%s\n",sendline);
        sent = writen(clientfd, sendline, nbytes);
    }
   close(fp);
}else
    perror("Open file");

The 'writen' function is:

ssize_t writen(int fd, const void *vptr, size_t n){
/* Write "n" bytes to a descriptor. */
size_t      nleft;
ssize_t     nwritten;
const char  *ptr;

ptr = vptr;
nleft = n;
while (nleft > 0) {
    if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
        if (nwritten < 0 && errno == EINTR)
            nwritten = 0;       /* and call write() again */
        else
            return(-1);         /* error */
    }

    nleft -= nwritten;
    ptr   += nwritten;
}
return(n);
}

The client-side code is:

   while (fgets(sendline, 10000,stdin) != NULL)
{
  sendto(sockfd,sendline,strlen(sendline),0,
         (struct sockaddr *)&servaddr,sizeof(servaddr));
  read(sockfd,recvline,10000);
  fputs(recvline,stdout);
  recvline[n]=0;
  if((recvline[0]=='-')&&(recvline[1]=='E')&&(recvline[2]=='R')&&(recvline[3]=='R')){
      close(sockfd);
      exit(1);
  }

}

The strange client that I get is in the image. Client Output

So what's my mistake? Why do I receive this kind of output and how could I fix it?

Upvotes: 0

Views: 685

Answers (2)

Rohan
Rohan

Reputation: 53326

Couple of issues,

In server code, parenthesis is at incorrect place,

while ( (nbytes = fread(sendline, sizeof(char), 512, fp) > 0)){

should be

while ( (nbytes = fread(sendline, sizeof(char), 512, fp)) > 0){
                                               ---------^ parenthesis close here

And in client side, set '\0' in recvline before printing as

n = read(sockfd,recvline,10000);
recvline[n] = '\0'
fputs(recvline,stdout);

Upvotes: 1

Flora Maud
Flora Maud

Reputation: 11

You never check how many bytes read returned (or whether it failed). Even if it does return n bytes as you assume, you don't null-terminate the buffer until after you print it, so fputs(recvline,stdout) will print whatever garbage it finds in the uninitialized buffer on the stack.

Upvotes: 1

Related Questions