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)