Example of sending and receiving files through linuxc socket-multithreading and resumable Data Transfer

Source: Internet
Author: User
Tags file info socket error tmp file

A small example of using a socket to send and receive files based on TCP/IP protocol in Linux C.

Confused by myself...

General steps:

Bytes --------------------------------------------------------------------------------------------------------------------------

Server --------------------------------------- --Client

1. Recv file name <------------------------------ Send File Name

2. Get File seek

3. Send File seek POS ---------------------> Recv file seek POS

4. | file open-> file seek-> File Read

5. Socket read <------------------------------- socket write

6. File wirte & Save seek POS

Bytes ----------------------------------------------------------------------------------------------------------------------------

Server:
/******** Http://blog.csdn.net/robertkun ********* // ********* server program (server. c) ************ // when reading files larger than 2 GB in Linux, specify # DEFINE _ file_offset_bits 64 # include <stdlib. h> # include <stdio. h> # include <errno. h> # include <string. h> # include <unistd. h> # include <netdb. h> # include <sys/socket. h> # include <netinet/in. h> # include <sys/types. h> # include <ARPA/inet. h> # include <fcntl. h> # include <pthread. h> # include <semaphore. h> // Define the package size as 512kb # define pack_size 1024*512 # define thread_num 5pthread_t a_thread [thread_num]; void * workthread (void * ARGs ); void printtrdid (const char * s); unsigned long getfileseek_long (const char * file_name); void encode (const char * file_name, char * cseek_pos); void writefileseek (const char * file_name, unsigned long seek_pos); struct trditem {int sockfd; struct sockaddr_in ADDR ;}; int main (int RGC, char * argv []) {// set the output buffer setvbuf (stdout, null, _ ionbf, 0); fflush (stdout); int sockfd, new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size, portnumber; char Hello [] = "Hello! Are you fine? \ N "; if (portnumber = atoi (" 8080 ") <0) {fprintf (stderr," Usage: % s portnumber \ A \ n ", argv [0]); exit (1);}/* the server starts to establish the socket descriptor */If (sockfd = socket (af_inet, sock_stream, 0 )) =-1) {fprintf (stderr, "socket error: % s \ n \ A", strerror (errno); exit (1 );} /* fill the sockaddr structure on the server */bzero (& server_addr, sizeof (struct sockaddr_in); server_addr.sin_family = af_inet; fill = htonl (inaddr_any); Weight = Hton S (portnumber);/* bind the sockfd descriptor */If (BIND (sockfd, (struct sockaddr *) (& server_addr), sizeof (struct sockaddr) =-1) {fprintf (stderr, "BIND error: % s \ n \ A", strerror (errno); exit (1 );} /* Listen to the sockfd descriptor */If (Listen (sockfd, 5) =-1) {fprintf (stderr, "Listen error: % s \ n \ ", strerror (errno); exit (1);} struct trditem item; item. sockfd = sockfd; item. ADDR = client_addr; // create five threads to listen to int I = 0; for (I = 0; I <thread_num; ++ I) {int er R = 0; err = pthread_create (& a_thread [I], null, workthread, (void *) & item); If (Err! = 0) {printf ("cannot create thread... % s \ n ", strerror (ERR) ;}// wait for five threads to end for (I = 0; I <thread_num; ++ I) {int err = 0; err = pthread_join (a_thread [I], null); If (Err! = 0) {printf ("the thread ID: % d ends failes, % s \ n", I, strerror (ERR ));}} printtrdid ("\ n \ nmain thread. "); sleep (5); close (sockfd); exit (0);} void * workthread (void * ARGs) {While (1) {fprintf (stderr, "server is listening! \ N ");/* server blocking until the Client Program establishes a connection */INT sin_size = 0; int new_fd = 0; struct trditem t_item = * (struct trditem *) ARGs; sin_size = sizeof (struct sockaddr_in); If (new_fd = accept (t_item.sockfd, (struct sockaddr *) (& t_item.addr), (socklen_t *) & sin_size) =-1) {fprintf (stderr, "Accept error: % s \ n \ A", strerror (errno); exit (1) ;}fprintf (stderr, "server get connection from % s \ n", inet_ntoa (t_item.addr.sin_addr); // print thread I Dprinttrdid ("Child thread. "); int order_id = 0; unsigned long read_size = 0; unsigned long file_len = 0; unsigned long seek_pos = 0; char file_name [128] = {'\ 0 '}; char file_info [1024] = {'\ 0'}; // read the command printf ("\ n \ nwaiting for read file info! \ N "); int nn = 0; If (nn = read (new_fd, file_info, 1024) {// instruction idint id_h = (INT) file_info [0] <8; order_id = id_h + (INT) file_info [1]; // file length // 16-bit unsigned long len_hig_1 = 0; memcpy (& len_hig_1, & file_info [2], sizeof (file_info [2]); unsigned long len_hig_2 = 0; memcpy (& len_hig_2, & file_info [3], sizeof (file_info [3]); unsigned long len_hig = len_hig_1 * 256 + len_hig_2; // low 16-bit unsigned long len_low_1 = 0; m Emcpy (& len_low_1, & file_info [4], sizeof (file_info [4]); unsigned long len_low_2 = 0; memcpy (& len_low_2, & file_info [5], sizeof (file_info [5]); int len_low = len_low_1 * 256 + len_low_2; file_len = len_hig * 256*256 + len_low; // file name strncpy (file_name, & file_info [6], strlen (& file_info [6]); printf ("Order = % d, % lu, % s \ n", order_id, file_len, file_name ); if (strlen (file_name) = 0) | (file_len = 0) {PRI Ntf ("Read File info error! \ N file_name or file_len is zero! \ N "); close (new_fd); close (t_item.sockfd); continue;} // obtain the breakpoint position of the object. (saved in. in the tmp file) char * cseek_pos = (char *) calloc (128, sizeof (char); getfileseek_char (file_name, cseek_pos); seek_pos = getfileseek_long (file_name); If! = NULL) {// the breakpoint is successfully obtained and sent to the client if (write (new_fd, cseek_pos, 128) =-1) {fprintf (stderr, "write error: % s \ n ", strerror (errno); close (new_fd); close (t_item.sockfd); Continue ;}} else {printf (" Read File info error! \ N "); close (new_fd); close (t_item.sockfd); continue;} // write the file printf (" \ n \ nwaiting for read file content! \ N "); file * pF = fopen (file_name," AB + "); If (pF = NULL) {printf (" Open File error! \ N "); close (new_fd);} Char buff [pack_size] = {'\ 0'}; int idx = 0; while (read_size <= file_len) {int rlen = read (new_fd, buff, pack_size); If (rlen) {int wn = fwrite (buff, sizeof (char), rlen, Pf); read_size + = rlen; seek_pos + = rlen; // After receiving certain data, the received information is displayed if (idx ++ % 5000 = 0) {printf ("% d, file Len = % lD, file seek = % lD, file read = % LD \ n ", idx, file_len, seek_pos, read_size) ;}} else {printf (" read over !... % D \ n ", rlen); break ;}// when the client is disconnected, save the breakpoint position writefileseek (file_name, seek_pos); printf (" file name = % s, file Len = % lD, already read size = % lD, file seek = % LD \ n ", file_name, file_len, read_size, seek_pos ); /* this communication has ended */fclose (PF); close (new_fd);} return (void *) NULL;} void printtrdid (const char * s) {pid_t PID; pthread_t tid; pid = getpid (); tid = pthread_self (); printf ("% s pid = % u tid = % u (0x % x) \ n", S, P ID, tid, tid);} unsigned long getfileseek_long (const char * file_name) {// obtain the breakpoint position char * file_seek = (char *) calloc (1024, sizeof (char); strcpy (file_seek, file_name); char temp [] = {". TMP "}; strcat (file_seek, temp); file * pF = fopen (file_seek," R "); If (pF = NULL) {printf (" Open File error! \ N "); Return 0;} Char cseek_pos [20] = {'\ 0'}; fseek (PF, 0, seek_set); fread (cseek_pos, sizeof (char ), sizeof (cseek_pos), Pf); fclose (PF); unsigned long seek = 0; Seek = strtol (cseek_pos, null, 10); printf ("file seek position (ulong) = % LD \ n ", seek); Return seek;} void getfileseek_char (const char * file_name, char * cseek_pos) {// obtain the breakpoint position char * file_seek = (char *) calloc (1024, sizeof (char); strcpy (file_seek, Fil E_name); char temp [] = {". TMP "}; strcat (file_seek, temp); file * pF = fopen (file_seek," R "); If (pF = NULL) {printf (" Open File error! \ N "); return;} fseek (PF, 0, seek_set); fread (cseek_pos, sizeof (char), 128, Pf); fclose (PF ); printf ("file seek position (char) = % S % d \ n", cseek_pos, sizeof (cseek_pos);} void writefileseek (const char * file_name, unsigned long seek_pos) {// write the file char * file_seek = (char *) calloc (1024, sizeof (char); strcpy (file_seek, file_name ); char temp [] = {". TMP "}; strcat (file_seek, temp); file * pF = fopen (file_seek ," WB + "); If (pF = NULL) {printf (" Open File error! \ N "); return;} int wn = fprintf (PF," % lD ", seek_pos); fclose (PF); If (wn =-1) {printf ("Write File seek position! Error! % D \ n ", wn); Return ;}}
Client:
Now it is based on QT ..

Makefile:

Server:

object=server.oserver.o:        gcc -g -c server.c        gcc -o server $(object)clean:        rm server $(object)

Client:

object=client.oclient.o:        gcc -g -c client.c        gcc -o client $(object)clean:        rm -rf client $(object)

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.