2

I have to make a server-client file tranfer using UDP . I have created a basic server which receives message sent by client . That's all. Now comes the major part :-

1. The message sent by client is the name of file .
2. Now the server checks whether there exists this file or not .
3. If there exists it sends the file to the client and it also keeps the count of the     number of requests of file made by the client .

I am new to this and i don't get it how to proceed further .

Here is the Server Code

#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<string.h>




int main()
{

  char buff[2000];
  char file_buffer[2000];
  int sd,connfd,len;

  struct sockaddr_in servaddr,cliaddr;

  sd = socket(AF_INET, SOCK_DGRAM, 0);

  if(sd==-1)
    {
      printf(" socket not created in server\n");
      exit(0);
    }
  else
    {
      printf("socket created in  server\n");
    }

  bzero(&servaddr, sizeof(servaddr));

  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = INADDR_ANY;
  servaddr.sin_port = htons(7802);

  if ( bind(sd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0 )
    printf("Not binded\n");
  else
    printf("Binded\n");



  len=sizeof(cliaddr);

  recvfrom(sd,buff,1024,0,
   (struct sockaddr *)&cliaddr, &len);

  printf("%s\n",buff);
  /* */
  FILE *fp;
  fp=fopen(buff,"r");
  if(fp==NULL)
    {
      printf("file does not exist\n");
    }

  fseek(fp,0,SEEK_END);
  size_t file_size=ftell(fp);
  fseek(fp,0,SEEK_SET);
  if(fread(file_buffer,file_size,1,fp)<=0)
    {
      printf("unable to copy file into buffer\n");
      exit(1);
    }
  if(sendto(sd,file_buffer,strlen(file_buffer),0,  (struct sockaddr *)&cliaddr, &len)<0)    {
    printf("error in sending the file\n");
    exit(1);
  }
  bzero(file_buffer,sizeof(file_buffer));


  /* */
  close(sd);

  return(0);
}

Here is the client code

#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include<netinet/in.h>
#include<sys/types.h>



int main()
{
    char buff[2000];
    int sockfd,connfd,len;

struct sockaddr_in servaddr,cliaddr;

// create socket in client side
sockfd = socket(AF_INET, SOCK_DGRAM, 0);

if(sockfd==-1)
{
    printf(" socket not created in client\n");
    exit(0);
}
else
{
    printf("socket created in  client\n");
}


bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY; // ANY address or use specific address
servaddr.sin_port = htons(7802);  // Port address


    printf("Type ur  UDP client message\n");
    scanf("%s",buff);

// send  msg to server

sendto(sockfd, buff, strlen(buff), 0,
          (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
      char file_buffer[2000];

    if (recvfrom(sockfd,file_buffer,2000,0,  (struct sockaddr *)&servaddr, sizeof(struct sockaddr))<0)
    {
      printf("error in recieving the file\n");
      exit(1);
    }

  char new_file[]="copied";
  strcat(new_file,buff);
  FILE *fp;
  fp=fopen(new_file,"w+");
  if(fwrite(file_buffer,1,sizeof(file_buffer),fp)<0)
    {
      printf("error writting file\n");
      exit(1);
    }


  //close client side connection
    close(sockfd);

return(0);
}

I have edited the programme and created a new buffer file_buffer , The server reads the data from file and writes into it and send to the client , On the other end client receive the data and make duplicate of this file and write into it. But on compiling it gives error in writting the file :(

user2714823
  • 607
  • 5
  • 15
  • 29
  • You have to make sure the receiver does not try to read in more data then sender sent. Otherwise the receiver might block, waiting forever for data never arriving. If the amount of data isn't constant or somehow known in advance, one will not get around to implement a minimum kind of protocol. – alk Sep 01 '13 at 07:59

3 Answers3

1

You will have to extend the logic at both places. Basically for the server code, you can use the buff as the filename and check if it exists. You can use "fopen (buff, "r" )" -- if this returns NULL, then the file does not exist and in that case you might want to send the client a note saying that the file does not exist. Something like this:

FILE *istream;
strncpy(fileName, buff, ret_len + 1);
if ( (istream = fopen(fileName, "r" ) ) == NULL ){
    printf ( "file non-existant!\n" );
    strncpy(buff, "Does not Exist", strlen("Does Not Exist"));
} else {
    printf ( "file exists!\n" );
    strncpy(buff, "Does Exist", strlen("Does Exist"));
    fclose (istream );
}

ret_len = sendto(sd, buff, strlen(buff), 0, (struct sockaddr *)&cliaddr, sizeof(struct sockaddr));
if (ret_len < 0) {
fprintf(stderr, "sendto() failed [ret value: %d]\n", ret_len);
return -1;
}

If the file exists, then read the file and send the content to the file.

The client must do a recvfrom() from the server after it sends the buffer to the server! Something like this. Note that you can use a numeric value (-1 or 0) to indicate if the file exists or not. And if the file exists, you can probably pass the file length in the initial message -- this way, the client would know how much data it needs to read.

// send  msg to server
sendto(sockfd, buff, strlen(buff) + 1, 0, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));

// recveive from server
ret_len = recvfrom(sockfd, buff, 1024, 0, NULL, 0);
printf("Received from server: %s \n",buff);

if (strncmp(buff, "Does not Exist", strlen("Does not Exist")) == 0)
    printf("File does not exist\n");
else if (strncmp(buff, "Does Exist", strlen("Does Exist")) == 0)
    printf("File does exist\n");
else
    printf("Unknown message\n");

Btw, in the above code, we need to add 1 to account for the NUL character. Also, once this step is done, the client code should call recvfrom() in a loop to receive data from the server, as communicated in the earlier step.

Note that if the file is too big, then you probably want to read it only as much as the message you want to send -- with UDP you can send upto 64K but you should ideally send only upto 1 MUT (around 1500 bytes).

Manoj Pandey
  • 4,528
  • 1
  • 17
  • 18
  • 1
    `scanf()` adds the `0`-terminator when scanning in a "string". There is no need to add one afterwards. – alk Sep 01 '13 at 07:55
  • i tried doing it myself but the programme doesn't work :| Could you please help me out? – user2714823 Sep 01 '13 at 08:58
  • Well, what is not working. You will have to debug this in steps. First make sure that the file name is communicated from teh client to the server. Next, make sure that the server opens the file correctly (verify for both cases by passing a valid name and an invalid name). The next step would be to have the server return the message (whether file exists or not). After that, the client needs to issue recvfrom() and get hte message. – Manoj Pandey Sep 01 '13 at 09:00
  • I guess the client is not able to write the data in a new file . It gives error in writting the file . – user2714823 Sep 01 '13 at 09:05
  • So, you are saying that the server confirms that the file exists and then starts sending pieces of that file. The client is supposed to open a new file and write these pieces to it. So, basically, it should open the file in append mode so that it can keep appending pieces into that file as and when it gets the info from server. Can you share that snippet? – Manoj Pandey Sep 01 '13 at 09:07
  • i already have in the above code. I have included that chunk of code in the above one itself ( i have specified the edits i made ) – user2714823 Sep 01 '13 at 09:10
  • Are you missing the NUL char when sending the file name from client to server? Please update strlen(buff) to "strlen(buff) + 1" in the sendto call. – Manoj Pandey Sep 01 '13 at 09:19
1

I wasn't sure if you had to develop your own client/server or if you could use others? There are a few other open source UDP based file transfer systems like UDT, UFTP, Tsunami-UDP, and even Google's QUIC.

Pierz
  • 7,064
  • 52
  • 59
0

Do you want the server to behave like a FTP server?

After receiving a filename from client, check whether it exists. See What's the best way to check if a file exists in C? (cross platform). Then open the file and send it buffer by buffer(e.g. 200 bytes at a time) to client. Simutaneously, the client receive it and write to a new file named filename.

Community
  • 1
  • 1
sensor
  • 61
  • 1
  • 1
  • 9