Linux network programming based on UDP for reliable file transfer example _c language

Source: Internet
Author: User
Tags htons

People who understand the network transport protocol know that it is easy to use TCP to implement file transfer. As opposed to TCP, because UDP is a connectionless, unreliable transport protocol, we need to consider the issue of packet loss and the first to (packet order), so we want to implement UDP transfer files, we need to solve these two problems. The method is to number the packet, received and stored in the order of the package, the receiver sends the confirmation message to the sender after receiving the data packet, and the sender sends the next packet after receiving the confirmation data, if the receiver receives the packet number is not the expected number, then the sending end is required to resend.

The following shows a Linux based on the C language implementation of a sample program, which defines a package structure, which contains data and headers, Baotou contains the number of packages and data size, after testing, the program can successfully transfer a video file.

The specific implementation code is as follows:

The server-side code is as follows:

/************************************************************************* > File name:server.c > Author:so Nglee ************************************************************************/#include <sys/types.h> # include<sys/socket.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> # include<stdio.h> #include <stdlib.h> #include <errno.h> #include <netdb.h> #include < stdarg.h> #include <string.h> #define SERVER_PORT 8000 #define BUFFER_SIZE 1024 #define FILE_NAME_MAX_SIZE 5 
  12/* Header * * typedef struct {int id; 
int buf_size; 
 
}packinfo; 
  /* Receive Package * * struct Sendpack {packinfo head; 
Char Buf[buffer_size]; 
 
 
} data; 
 
  int main () {/* Send ID */int send_id = 0; 
 
  /* Receive ID */int receive_id = 0; 
  /* Create UDP Socket interface/struct sockaddr_in server_addr; 
  Bzero (&server_addr, sizeof (SERVER_ADDR)); 
  server_addr.sin_family = af_inet; Server_addr.sin_addr. s_addr = htonl (Inaddr_any); 
 
  Server_addr.sin_port = htons (Server_port); 
  /* Create socket */int SERVER_SOCKET_FD = socket (af_inet, SOCK_DGRAM, 0); 
    if (server_socket_fd = = 1) {perror ("Create socket Failed:"); 
  Exit (1); 
    /* Bind sleeve interface//if ( -1 = (Bind (server_socket_fd, (struct sockaddr*) &server_addr,sizeof (SERVER_ADDR))) { 
    Perror ("Server Bind Failed:"); 
  Exit (1); 
    /* Data transfer/while (1) {/* Defines an address for capturing the client address/struct sockaddr_in client_addr; 
 
    socklen_t client_addr_length = sizeof (CLIENT_ADDR); 
    /* Receive data */char buffer[buffer_size]; 
    Bzero (buffer, buffer_size); if (Recvfrom (server_socket_fd, buffer, buffer_size,0, (struct sockaddr*) &client_addr, &client_addr_length) = = 
      -1) {perror ("Receive Data Failed:"); 
    Exit (1); 
    /* * Copy out file_name/char file_name[file_name_max_size+1 from buffer; 
    Bzero (file_name,file_name_max_size+1); strncpy (file_name, buffer, strlen (buffer) >file_name_max_size? 
    File_name_max_size:strlen (buffer)); 
 
    printf ("%s\n", file_name); 
    /* Open File * * *FP = fopen (file_name, "R"); 
    if (NULL = fp) {printf ("file:%s not found.\n", file_name); 
      else {int len = 0; 
 
        /* Each read a piece of data, it will be sent to the client * * while (1) {Packinfo pack_info; 
          if (receive_id = = send_id) {++send_id; if (len = fread (data.buf, sizeof (char), buffer_size, FP)) > 0 {data.head.id = send_id;/* Send I D put in Baotou, used for labeling order * * data.head.buf_size = len; /* Record Data length */if (sendto (SERVER_SOCKET_FD, char*) &data, sizeof (data), 0, (struct sockaddr*) &client_add 
              R, Client_addr_length) < 0) {perror ("Send File Failed:"); 
            Break /* Receive confirmation message/* RECVFROM (SERVER_SOCKET_FD, (char*) &pack_info, sizeof (Pack_info), 0, (struct s Ockaddr*) &client_addr, &client_addr_length);  
          receive_id = pack_info.id; 
          } else {break; If the ID received and the ID sent are not the same, resend/if (SendTo server_socket_fd, char* ) &data, sizeof (data), 0, (struct sockaddr*) &client_addr, Client_addr_length) < 0) {per 
            Ror ("Send File Failed:"); 
          Break /* * Receive confirmation message/* RECVFROM (SERVER_SOCKET_FD, (char*) &pack_info, sizeof (Pack_info), 0, (struct Socka 
          ddr*) &client_addr, &client_addr_length);  
        receive_id = pack_info.id; 
      }/* Close File/* fclose (FP); 
    printf ("file:%s Transfer successful!\n", file_name); 
  } close (SERVER_SOCKET_FD); 
return 0; 

 }

The

client-side code is as follows:

/************************************************************************* > File name:client.c > Author:so Nglee ************************************************************************/#include <sys/types.h> # include<sys/socket.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> # include<stdio.h> #include <stdlib.h> #include <errno.h> #include <netdb.h> #include < stdarg.h> #include <string.h> #define SERVER_PORT 8000 #define BUFFER_SIZE 1024 #define FILE_NAME_MAX_SIZE 5 
  12/* Header * * typedef struct {int id; 
int buf_size; 
 
}packinfo; 
  /* Receive Package * * struct Recvpack {packinfo head; 
Char Buf[buffer_size]; 
 
 
} data; 
 
  int main () {int id = 1; 
  /* Service End Address * * struct sockaddr_in server_addr; 
  Bzero (&server_addr, sizeof (SERVER_ADDR)); 
  server_addr.sin_family = af_inet; 
  SERVER_ADDR.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1"); Server_addr.sin_port =Htons (Server_port); 
 
  socklen_t server_addr_length = sizeof (SERVER_ADDR); 
  /* Create socket */int CLIENT_SOCKET_FD = socket (af_inet, SOCK_DGRAM, 0); 
    if (CLIENT_SOCKET_FD < 0) {perror ("Create socket Failed:"); 
  Exit (1); 
  /* Enter filename to buffer */char file_name[file_name_max_size+1]; 
  Bzero (file_name, file_name_max_size+1); 
  printf ("Please Input File Name on Server:"); 
 
  scanf ("%s", file_name); 
  Char Buffer[buffer_size]; 
  Bzero (buffer, buffer_size); strncpy (buffer, file_name, strlen (file_name) >buffer_size? 
 
  Buffer_size:strlen (file_name)); /* Send file name */if (sendto (client_socket_fd, buffer, buffer_size,0, (struct sockaddr*) &server_addr,server_addr_length) 
    < 0) {perror ("Send File Name Failed:"); 
  Exit (1); 
  * * Open the file, ready to write/file *FP = fopen (file_name, "w");  
    if (NULL = fp) {printf ("file:\t%s Can not be Open to write\n", file_name); 
  Exit (1); 
  /*/* receive data from the server and write to file */int len = 0; while (1) { 
    Packinfo Pack_info; if (len = Recvfrom (client_socket_fd, (char*) &data, sizeof (data), 0, (struct sockaddr*) &server_addr,& 
        server_addr_length)) > 0) {if (data.head.id = = id) {pack_info.id = data.head.id; 
        Pack_info.buf_size = data.head.buf_size; 
        ++id; /* Send packet Confirmation information */if (sendto (CLIENT_SOCKET_FD, char*) &pack_info, sizeof (Pack_info), 0, (struct sockaddr*) &s 
        ERVER_ADDR, Server_addr_length) < 0) {printf ("Send Confirm information failed!"); 
        /* Write File/*/if (fwrite (data.buf, sizeof (char), data.head.buf_size, FP) < data.head.buf_size) 
          {printf ("file:\t%s Write failed\n", file_name); 
        Break 
        Or else if (Data.head.id < ID)/* If it is a heavily-sent package */{pack_info.id = data.head.id; 
        Pack_info.buf_size = data.head.buf_size; /* Re-send packet confirmation/if (SendTo client_socket_fd,(char*) &pack_info, sizeof (Pack_info), 0, (struct sockaddr*) &server_addr, Server_addr_length) < 0) { 
        printf ("Send Confirm information failed!"); 
    } else {}} else {break; 
  } printf ("Receive file:\t%s from Server IP successful!\n", file_name); 
  Fclose (FP); 
  Close (CLIENT_SOCKET_FD); 
return 0;

 }

Interested friends can test the program, I believe it will be Linux under the C language Network programming to bring certain help.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.