Link to home
Start Free TrialLog in
Avatar of arijit_rebaca
arijit_rebaca

asked on

stranigh o/p for file transfer

Hi,

I write a simple client server application that can transfer file over network. When client and server application are working in same m/c it is working fine...
But when they are running from diff m/c ... then at the client side file is created but no data is there.. why it is happening? I used foen, fgets, fputs for file read write....

another question, it was a .sh file. If it is a .zip / dll file then will I do the same thing as before for file read write ?
Avatar of sunnycoder
sunnycoder
Flag of India image

Hi arijit_rebaca,

> why it is happening? I used foen, fgets, fputs for file read write....
show code
 
> another question, it was a .sh file. If it is a .zip / dll file then
> will I do the same thing as before for file read write ?
yes ... but make sure all I/O is done in binary mode ...

Cheers!
sunnycoder
Avatar of arijit_rebaca
arijit_rebaca

ASKER

client :
int main(int argc, char *argv[])
{
    int sockfd, numbytes,new_fd;
    char buf[MAXDATASIZE];
    //struct hostent *he;
    struct sockaddr_in their_addr; /* connector's address information */
    void WriteFile(char*,int);
    if (argc != 2)
    {
       fprintf(stderr,"usage: client hostname\n");
       exit(1);
    }
    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
    {
       perror("Client socket:");
       exit(1);
    }
        new_fd = sockfd;
    memset(&(their_addr), 0, sizeof(their_addr));
    their_addr.sin_family = AF_INET;      /* host byte order */
    their_addr.sin_port = htons(PORT);    /* short, network byte order */
  //  their_addr.sin_addr = *((struct in_addr *)he->h_addr_list[0]);
    //their_addr.sin_addr = inet_addr("127.0.0.1");
        if(!inet_aton(argv[1],&(their_addr.sin_addr)) )
        {
                printf("Fail\n");
                exit(0);
        }
    if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
    {
        perror("Client connect:");
        exit(1);
   }
    if (send(sockfd, "GET\0",9, 0) == -1)
        perror("Client send");
    if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1)
    {
        perror("client recev");
        exit(1);
    }
    printf("\t\t%s\n",buf);
    if (send(sockfd, "test.sh\0",7, 0) == -1)
        perror("Client send");
        if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1)
        {
                perror("client recev");
                exit(1);
        }
        printf("\t\t%s\n",buf);
        WriteFile("test.c",sockfd);
}
void WriteFile(char *filename,int sockfd)
{
         FILE *fp;
         int rd = 1;
         char buf[200];
         if((fp = fopen("clienttest.sh","a")) == 0)
         {
                printf("Error in Openning File\n");
                exit;
         }
         printf("\nSuccess in Opening File\n");
         while (rd > 0)
         {
                if ((rd=recv(sockfd, buf, MAXDATASIZE, 0)) == -1)
                {
                        perror("client recev");
                        exit(1);
                }
                fputs(buf,fp);
         }
         fclose(fp);
}
SERVER:
int main()
{
   int sockfd, new_fd, nsel,connfd;  /* listen on sock_fd, new connection on new_fd
   int numbytes;
   struct sockaddr_in my_addr;    /* my address information */
   struct sockaddr_in their_addr; /* connector's address information */
   int sin_size;
   char buf[MAXDATASIZE];
   char *getstr;
   void ReadFile(char* , char*i , int);
   char addbuf[100];
   char filebuf[100];
   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
   {
       perror("Server socket:");
       exit(1);
   }
   memset(&(my_addr), 0, sizeof(my_addr));        /* zero the rest of the struct */
   my_addr.sin_family = AF_INET;         /* host byte order */
   my_addr.sin_port = htons(MYPORT);     /* short, network byte order */
   my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
   if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
   {
       perror("Server bind:");
       exit(1);
   }
   if (listen(sockfd, BACKLOG) == -1)
   {
        perror("Server listen:");
        exit(1);
   }
   sin_size = sizeof(struct sockaddr_in);
while(1)
{
   if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
   {
        perror("Server accept");
        exit(0);
               //continue;
   }
   printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));
   if ((numbytes=recv(new_fd, addbuf, MAXDATASIZE, 0)) == -1)
   {
        perror("server recv");
        exit(1);
   }
   printf("\t\t%s\n",addbuf);
   if (send(new_fd,"SENDFILENAME\0", 13,0) == -1)
                perror("server send");
   if ((numbytes=recv(new_fd, filebuf, MAXDATASIZE, 0)) == -1)
   {
        perror("server recv");
        exit(1);
   }
   printf("\t\t%s\n",filebuf);
   if (send(new_fd,"DOWNLOAD\0", 9,0) == -1)
                perror("server send");
   ReadFile(addbuf,filebuf,new_fd);
        close(sockfd);
}
        return 0;
}
void ReadFile(char *address, char *filename, int sockfd)
{
       #define MAX 10
        char buf[MAX];
        FILE *fp;
        int result;
        if((fp = fopen(filename, "r")) == 0)
        {
                printf("Error in Openning File\n");
                exit;
        }
        printf("\nSuccess in Opening File\n");
        while (fgets(buf, 10, fp) != 0)
        {
               if (send(sockfd,buf,strlen(buf),0) == -1)
                        perror("server send");
        }
        fclose(fp);
}
how do I make sure all I/O are in binary mode...?
Hi arijit_rebaca,

Client side code looks ok ... run it through a debugger to make sure that you are indeed getting some data ..
> if (send(sockfd, "test.sh\0",7, 0) == -1)
the \0 is not explicitly required ... remove it
It could be that your first recv in main is getting the data and recv() in WriteFile() just waits for ever? Check that possibility

>         if((fp = fopen("clienttest.sh","a")) == 0)
>         {
>                printf("Error in Openning File\n");
>                exit;     ------------- exit(1);?
>         }

>how do I make sure all I/O are in binary mode...?
open files with "b" flag ... (matter only on windows)
Do not use any string functions such as fgets/fputs/strlen/strcmp etc. ... only those which treat data as binary .. e.g. fread, memcpy etc.

Cheers!
sunnycoder
what are you passing as a parameter?
must be in the form  like 192.168.4.45

is it connecting successfully?

as sunny has already pointed out. Dont use fputs in writefile() and fgets() in readfile. Because this will get incorrect results for binary files.
use fwrite() and fread();

regards
Manish Regmi
You need to check a few things :

1) is the other machine reachable ? ie. is your network correctly configured ? Try pinging the machine.

2) did you specify the correct ip address (or hostname) and port ?

3) is the machine on the same network ? Is there a router, proxy or firewall in between ? Then you'll need some extra configuration :

     a) router : forward the necessary ports correctly
     b) proxy : configure your application to make use of the proxy if needed
     c) firewall : add some rules to allow the traffic from and to your application (port)
ok it is solved. but another problem I face is that... dll file is transfer well. but when I check it with the original with diff comman it shows that binary files are different.....

here is file read/write code...

server side:

ReadFile(...)
{
        FILE *input = NULL;
        char buf[20];

  /* open the file in binary mode for read only */
        input = fopen("SHAPERESOLVER.DLL", "rb");
        if (input == NULL)
        {
                printf("cant open File");
                exit(1);
        }
  /* read dwords from the file */
        while (!feof(input))
        {
               fread(buf, sizeof(buf), 1, input);
                if (send(sockfd,buf,strlen(buf),0) == -1)
                        perror("server send");
        }
        fclose(input);
}

client side :
WriteFile(..)
{
       FILE *input = NULL;
       char buf[20];
       int rd = 1;
       input = fopen("CSHAPERESOLVER.DLL", "ab");
       if (NULL == input)
       {
               printf("cant open filename");
               exit(1);
       }
       while (rd > 0)
       {
              if ((rd=recv(sockfd, buf, 20, 0)) == -1)
               {
                       perror("client recev");
                       exit(1);
               }
               fwrite(buf, sizeof(buf), 1, input);
       }
       fclose(input);
}

Where is the problem ?? why files are different?


>if (send(sockfd,buf,strlen(buf),0) == -1)

Dont use strlen
ASKER CERTIFIED SOLUTION
Avatar of manish_regmi
manish_regmi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I have changed the following ... but again the difference comes....

Is the line is ok ?
 
   fwrite(buf, sizeof(buf), 1, input);

can you be more specific about the difference ...
Is it the CRLF bytes which are different ... Or is there some significant difference in size? Keep a count of number of bytes transmitted and received ... what are the respective counts?
no byte size of two files are same...
then what is the difference ?
diff o/p is :
Binary files CSHAPERESOLVER.DLL and SHAPERESOLVER.DLL differ only.... it shows no detail
then use a hex editor or a comparison utility which would show the exact difference
in readfile, change

int bytesread;

 bytesread = fread(buf, sizeof(buf), 1, input);
     if (send(sockfd,buf,bytesread,0) == -1)
                        perror("server send");


In writefile, you are reading 20 bytes but writing sizeof(buff),

 while (rd > 0)
       {
              if ((rd=recv(sockfd, buf, 20, 0)) == -1)
               {
                       perror("client recev");
                       exit(1);
               }
               fwrite(buf, rd, 1, input);
       }
       fclose(input);

regards
Manish regmi
I used
vi -i CSHAPERESOLVER.DLL SHAPERESOLVER.DLL


the o/p:
E575: viminfo: Illegal starting char in line: y

i think this is the only diff.
see if diff command would let you compare the binaries
hi Manish,

I change my code according to yr suggession ... but diff come
Use a utility that can handle binaries for getting the diff
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
what are u using to compare?

diff should compare binary files fine.

diff file1 file2

Also you are continuously appending to same file.
 input = fopen("CSHAPERESOLVER.DLL", "ab");

use this instead
  fopen("filename", "w+");

regards
Manihs Regmi
one thing is to be noted that...
I write the below code ..then also the diff come.. why?
int main()
       input1 = fopen("SHAPERESOLVER.DLL", "rb");
        input2 = fopen("CSHAPERESOLVER.DLL", "ab");
       while (!feof(input1))
        {       num = fread(buf, sizeof(buf), 1, input1);
                fwrite(buf, num, 1, input2);
        }
      fclose(input1);
     fclose(input2);
}
then also the diff come..
dooes the CSHAPERESOLVER.DLL exists before running that program.

Then your code is just appending to the existing file.

int main()
       input1 = fopen("SHAPERESOLVER.DLL", "rb");
        input2 = fopen("CSHAPERESOLVER.DLL", "wb");
       while (!feof(input1))
        {       num = fread(buf, sizeof(buf), 1, input1);
                fwrite(buf, num, 1, input2);
        }
      fclose(input1);
     fclose(input2);
}

what happens now.

regards
Manish Regmi
What is the output of the cmp command I showed earlier ?
 2   0 215
  3   0 115
  4  20 216
  5 215 105
  6 235   0
  7   0  24
  8  20   0
  9 115   1
 10 141 200
 11  37 266
 12  20   3
 13 216 130
 14 161   0
 15  12   0
 16 222   0
 17 105   0
 18 120   0
 19 117   1
 20 103   0
 22  40   1
 23   0 320
 24   0   1
 25  24  30
 26 266 174
 27  47   0
 28 272 324
 29   0  54
 31   0 136
 33   1   3
 34   0  10
 35 277   0
and so no...
That seems to indicate that the files are actually two completely different files !! Almost every single byte is different. Except the first.

Try manish_regmi's last suggestion ...
      while (!feof(input1))
        {       num = fread(buf, sizeof(buf), 1, input1);
                fwrite(buf, num, 1, input2);
        }

This loop is dangerous .... feof would return true after a read() has met EOF ... In case of reading the last chunk, fwrite() would be writing it twice since there is no check between fread and fwrite

I always prefer to have loops like

while (fread)
or
while (fgets)

Since your files are entirely different, the problem is more than this.
Make sure you are sending and receiving data as bytes ... Dont send them as words or structs since they would be interpreted differently on different endian machines.

Do text files behave all right?