An example of socket file transfer for Linux network programming

  • 2020-04-02 02:37:57
  • OfStack

The example program described in this paper is based on the Linux platform socket network programming, file transfer function. The example is a socket network file transfer program based on TCP stream protocol. Written in C language. Finally, the file transfer program can transfer any format file.

The specific implementation code is as follows:

The Server code is as follows:


 
 
#include<netinet/in.h> // sockaddr_in 
#include<sys/types.h>  // socket 
#include<sys/socket.h> // socket 
#include<stdio.h>    // printf 
#include<stdlib.h>   // exit 
#include<string.h>   // bzero 
 
#define SERVER_PORT 8000 
#define LENGTH_OF_LISTEN_QUEUE 20 
#define BUFFER_SIZE 1024 
#define FILE_NAME_MAX_SIZE 512 
 
int main(void) 
{ 
  //Declare and initialize a server-side socket address structure
  struct sockaddr_in server_addr; 
  bzero(&server_addr, sizeof(server_addr)); 
  server_addr.sin_family = AF_INET; 
  server_addr.sin_addr.s_addr = htons(INADDR_ANY); 
  server_addr.sin_port = htons(SERVER_PORT); 
 
  //Creates a socket and returns the socket descriptor if successful
  int server_socket_fd = socket(PF_INET, SOCK_STREAM, 0); 
  if(server_socket_fd < 0) 
  { 
    perror("Create Socket Failed:"); 
    exit(1); 
  } 
  int opt = 1; 
  setsockopt(server_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); 
 
  //Bind the socket and socket address structure
  if(-1 == (bind(server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)))) 
  { 
    perror("Server Bind Failed:"); 
    exit(1); 
  } 
   
  //The socket listening
  if(-1 == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE))) 
  { 
    perror("Server Listen Failed:"); 
    exit(1); 
  } 
 
  while(1) 
  { 
    //Defines the socket address structure of the client
    struct sockaddr_in client_addr; 
    socklen_t client_addr_length = sizeof(client_addr); 
 
    //Accept the connection request and return a new socket(descriptor) for communicating with the connected client
    //The accept function writes client information to client_addr
    int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length); 
    if(new_server_socket_fd < 0) 
    { 
      perror("Server Accept Failed:"); 
      break; 
    } 
 
    //The recv function receives data into the buffer
    char buffer[BUFFER_SIZE]; 
    bzero(buffer, BUFFER_SIZE); 
    if(recv(new_server_socket_fd, buffer, BUFFER_SIZE, 0) < 0) 
    { 
      perror("Server Recieve Data Failed:"); 
      break; 
    } 
 
    //Then copy from the buffer to the 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("%sn", file_name); 
 
    //Open the file and read the file data
    FILE *fp = fopen(file_name, "r"); 
    if(NULL == fp) 
    { 
      printf("File:%s Not Foundn", file_name); 
    } 
    else 
    { 
      bzero(buffer, BUFFER_SIZE); 
      int length = 0; 
      //Each time a piece of data is read, it is sent to the client and looped until the file is finished
      while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0) 
      { 
        if(send(new_server_socket_fd, buffer, length, 0) < 0) 
        { 
          printf("Send File:%s Failed./n", file_name); 
          break; 
        } 
        bzero(buffer, BUFFER_SIZE); 
      } 
 
      //Close the file
      fclose(fp); 
      printf("File:%s Transfer Successful!n", file_name); 
    } 
    //Close the connection to the client
    close(new_server_socket_fd); 
  } 
  //Close the socket for listening
  close(server_socket_fd); 
  return 0; 
} 

The Client code is as follows:


 
 
#include<netinet/in.h>  // sockaddr_in 
#include<sys/types.h>  // socket 
#include<sys/socket.h>  // socket 
#include<stdio.h>    // printf 
#include<stdlib.h>    // exit 
#include<string.h>    // bzero 
 
#define SERVER_PORT 8000 
#define BUFFER_SIZE 1024 
#define FILE_NAME_MAX_SIZE 512 
 
int main() 
{ 
  //Declare and initialize a client socket address structure
  struct sockaddr_in client_addr; 
  bzero(&client_addr, sizeof(client_addr)); 
  client_addr.sin_family = AF_INET; 
  client_addr.sin_addr.s_addr = htons(INADDR_ANY); 
  client_addr.sin_port = htons(0); 
 
  //Creates a socket and returns the socket descriptor if successful
  int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0); 
  if(client_socket_fd < 0) 
  { 
    perror("Create Socket Failed:"); 
    exit(1); 
  } 
 
  //Binding the client socket and the client socket address structure is not required
  if(-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr)))) 
  { 
    perror("Client Bind Failed:"); 
    exit(1); 
  } 
 
  //Declare a server-side socket address structure and initialize it with the server's IP address and port for subsequent connections
  struct sockaddr_in server_addr; 
  bzero(&server_addr, sizeof(server_addr)); 
  server_addr.sin_family = AF_INET; 
  if(inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) == 0) 
  { 
    perror("Server IP Address Error:"); 
    exit(1); 
  } 
  server_addr.sin_port = htons(SERVER_PORT); 
  socklen_t server_addr_length = sizeof(server_addr); 
 
  //Initiate a connection to the server, after a successful connection client_socket_fd represents a socket connection between the client and the server
  if(connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0) 
  { 
    perror("Can Not Connect To Server IP:"); 
    exit(0); 
  } 
 
  //Enter the file name and place it in a buffer waiting to be sent
  char file_name[FILE_NAME_MAX_SIZE+1]; 
  bzero(file_name, FILE_NAME_MAX_SIZE+1); 
  printf("Please Input File Name On Server:t"); 
  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)); 
   
  //Sends the data in the buffer to the server
  if(send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0) 
  { 
    perror("Send File Name Failed:"); 
    exit(1); 
  } 
 
  //Open the file and prepare to write
  FILE *fp = fopen(file_name, "w"); 
  if(NULL == fp) 
  { 
    printf("File:t%s Can Not Open To Writen", file_name); 
    exit(1); 
  } 
 
  //Receive data from the server to the buffer
  //Each time a piece of data is received, it is written to a file, loop until the file is received and written
  bzero(buffer, BUFFER_SIZE); 
  int length = 0; 
  while((length = recv(client_socket_fd, buffer, BUFFER_SIZE, 0)) > 0) 
  { 
    if(fwrite(buffer, sizeof(char), length, fp) < length) 
    { 
      printf("File:t%s Write Failedn", file_name); 
      break; 
    } 
    bzero(buffer, BUFFER_SIZE); 
  } 
 
  //Upon successful reception, close the file and close the socket
  printf("Receive File:t%s From Server IP Successful!n", file_name); 
  close(fp); 
  close(client_socket_fd); 
  return 0; 
} 

The program has more detailed comments, I believe it is not difficult to understand. Interested friends can on this basis to try to expand some functions, make its functions more powerful.


Related articles: