How to implement UDP reliable transmission

Source: Internet
Author: User
Tags bind socket strlen htons

As opposed to TCP, UDP is a non-connected, unreliable transport protocol.
If we want to use UDP to achieve reliable transmission, we need to solve two problems: packet loss and post-send first (packet order).

Workaround:
1) The packet number, according to the order of the packet received and stored;
2) The receiving end receives the packet to send the acknowledgment message to the sending side, the sending side receives the confirmation data to continue to send the next packet, if the receiving end receives the packet the number is not the expected number, then asks the sending side to resend.

Here is an example program:
The program defines a package structure, which contains data and headers, the header contains the package number and data size, after testing, the program can successfully transfer a video file.
The specific implementation code is as follows:

The 1.server terminal code is as follows:

#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 1024x768 #def 
  INE file_name_max_size 512/* Baotou */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 a 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); }/* Bound socket interface */if ( -1 = = (bind (server_socket_fd, struct sockaddr*) &server_addr,sizeof (SERVER_ADDR))) {PE 
    Rror ("Server Bind Failed:"); 
  Exit (1); 
    }/* Data transfer */while (1) {/* Defines an address for capturing 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 from buffer file_name */char file_name[file_name_max_size+1]; 
    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 Files */File *FP = fopen (file_name, "R"); if (NULL = = fp) {printf ("file:%s not found.\n", File_NAME); 
      } else {int len = 0; 

        /* Each time a piece of data is read, it is 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 into the header for marking order */data.head.buf_size = len; /* Record Data length */if (SendTo (SERVER_SOCKET_FD, (char*) &data, sizeof (data), 0, (struct sockaddr*) &client_addr 
              , client_addr_length) < 0) {perror ("Send File Failed:"); 
            Break }/* Receive confirmation message */Recvfrom (SERVER_SOCKET_FD, (char*) &pack_info, sizeof (Pack_info), 0, (struct so 
            ckaddr*) &client_addr, &client_addr_length);  
          receive_id = pack_info.id; 
          } else {break;
 }} else {/* If the received ID is not the same as the sent ID, Resend */         if (SendTo (SERVER_SOCKET_FD, (char*) &data, sizeof (data), 0, (struct sockaddr*) &client_addr, Client_addr_le 
            Ngth) < 0) {perror ("Send File Failed:"); 
          Break }/* Receive confirmation message */Recvfrom (SERVER_SOCKET_FD, (char*) &pack_info, sizeof (Pack_info), 0, (struct SOCKAD 
          dr*) &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

2.client Terminal code is as follows:

#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 1024x768 #def 
  INE file_name_max_size 512/* Baotou */typedef struct {int id; 
int buf_size; 

}packinfo; 
  /* Receive package */struct Recvpack {packinfo head; 
Char Buf[buffer_size]; 


} data; 

  int main () {int id = 1; 
  /* Server 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 file name 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 file, ready to write */File *FP = fopen (file_name, "w");  
    if (NULL = = fp) {printf ("file:\t%s Can not Open to write\n", file_name); 
  Exit (1); 
  }/* Receives data from the server and writes the 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 message */if (SendTo (CLIENT_SOCKET_FD, (char*) &pack_info, sizeof (Pack_info), 0, (struct sockaddr*) &se 
        RVER_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 
        }} else if (Data.head.id < ID)/* If it is a re-sent package */{pack_info.id = data.head.id; 
        Pack_info.buf_size = data.head.buf_size; /* Re-send packet acknowledgement */if (SendTo (CLIENT_SOCKET_FD, (char*) &pack_info, sizeof (Pack_info), 0, (struct sockaddr*) &se 
        RVER_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;
 }

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.