Server
/* *run command: *g++ server.cpp-o server &&./server */#ifndef server#define server#include<arpa/inet.h># include<assert.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include < errno.h> #include <assert.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <signal.h> const int servport = 5555;//Server listener port number const int BACKLOG = 10; Maximum simultaneous connection requests const int max_data_size = 1000;const int max_name_length = 21;const int max_phone_length = 15;const int Max_hom Eaddress_length = 61;struct Address{char name[max_name_length];char phone[max_phone_length];char home_address[MAX_ Homeaddress_length];int age;};/ /void insert_client_fd (int* client_list,int client_fd);//void accept_client ();//void* interact_with_client (void* clients_list); void* send_msg_to_client (int client_fd, char* msg), void sig_int (int signo); void Generate_phone (char* phone); void Generate_name (char* name); void generate_rand_n_address (int n); bool Find_phone_with_name (char* name, char* Phone), bool Find_name_with_phone (char* phone, char* name), bool Write_address (address** addresses, int n); void Print_ Addresses (); void handle_request (const int client_id, const char* BUF); void init (); void serv (); void Client_add (int* client, int fd), void Client_del (int* client, int fd), static char const* fileName = ". Address";//SOCK_FD: Listener socketstatic int sock_fd;/* * Read-write lock */pthread_rwlock_t rwlock;int main (int argc, char* argv[]) {init ();//accept_client (); serv (); return 0;} /* Initialize */void init () {if (Signal (SIGINT, sig_int) = = Sig_err) {perror ("signal (Sigint,sig_int)");} if (Signal (sigquit, sig_int) = = Sig_err) {perror ("signal (Sigquit,sig_int)");} Srand (Time (0));p rint_addresses ();//randomly generate 10//generate_rand_n_address (10);} void Serv () {if (SOCK_FD = socket (af_inet, sock_stream, 0)) = =-1) {perror ("Socket creation error"); _exit (1);} Local address information struct sockaddr_in my_addr;my_addr.sin_family = af_inet;mY_addr.sin_port = htons (servport); my_addr.sin_addr.s_addr = Inaddr_any;////inaddr_any;inet_addr (ServerIP);//printf ("%s\n", Inet_ntoa (MY_ADDR.SIN_ADDR)), Bzero (& (My_addr.sin_zero), 8);p rintf ("before bind\n"); if (Bind (SOCK_FD, struct sockaddr*) &my_addr, sizeof (my_addr)) = =-1) {perror ("Bind Error! "); exit (1);} printf ("Before listen\n"), if (Listen (SOCK_FD, BACKLOG) = =-1) {perror ("Listen error"); exit (1);} int Client[backlog + 1];memset (client,-1, sizeof (int) * (BACKLOG + 1));/* * The largest fd */int maxfd;fd_set rset, Allset; Fd_zero (&allset); Fd_set (sock_fd,&allset); maxfd = Sock_fd;for (;;) {RSet = allset;if (SELECT (maxfd + 1, &rset, NULL, NULL, NULL) < 0) {perror ("select Error");} CLIENT_FD: Data transfer socketint Client_fd;char buf[max_data_size];//monitoring fd Ready if (Fd_isset (Sock_fd,&rset)) {// Client address information struct sockaddr_in remote_addr;socklen_t sin_size;sin_size = sizeof (struct sockaddr_in);p rintf ("before accept\ n "); if ((client_fd = Accept (sock_fd, (struct sockaddr*) &remote_addr,&sin_size))= =-1) {perror ("Accept error \ n"); continue;} Client_add (client, CLIENT_FD); Fd_set (Client_fd,&allset);//adjust Maxfdif (client_fd>maxfd) maxfd=client_fd;printf ("received a connection from%s Assigned fd=%d\n ", Inet_ntoa (REMOTE_ADDR.SIN_ADDR), CLIENT_FD); if (vfork () = = 0) {//Service program: Child process//finish sending message, exit Char Buf[max_ data_size];sprintf (buf, "hello,your number is%d", client_fd); Send_msg_to_client (CLIENT_FD, buf); exit (0);}} There is a client sent to request for (int i = 0; I <= BACKLOG; i++) {client_fd = client[i];//printf ("client[%d]=%d\n", i,client_fd);//client_ FD has request if (client_fd > 0 && fd_isset (client_fd,&rset)) {int receivebytes = recv (client_fd, buf, Max_data_ SIZE, 0), if (receivebytes<0) {perror ("recv error!");} else if (receivebytes==0) {fd_clr (client_fd,&allset); Client_del (CLIENT,CLIENT_FD); close (CLIENT_FD);} Else{buf[receivebytes] = ';p rintf ("received cmd from%d:%s\n", CLIENT_FD, buf); if (strncmp (buf, "Quit", 4) = = 0) {FD_CLR (Client_fd,&allset); Client_del (CLIENT,CLIENT_FD); Close (CLIENT_FD);p rintf ("clIENT_FD id=%lu quit\n ", CLIENT_FD);} Elsehandle_request (CLIENT_FD, buf);}} if (client_fd > 0 && fd_isset (client_fd,&rset))}//for (int i = 0; I <= maxfd; i++)}}void Client_add (in t* client, int fd) {for (int i = 0; I <= BACKLOG; i++) {if (client[i] = = 1) {Client[i] = fd;break;//actually two times, forgetting break, programming level too low ...}} void Client_del (int* client, int fd) {for (int i = 0; I <= BACKLOG; i++) {if (client[i] = FD) client[i] = 1;}} void handle_request (const int client_id, const char* buf) {char* helpstring = "Help #显示可用的命令 \ n" "list #显示通讯录所有内容 (assuming no duplicate name) \ n" "Name thenamestring# query phone number \ n" "phon thephonenumberstring#phone query name \ n" "Shel #本地shell \ n" "Quit #quit \ n" "Inse #insert Temporarily do not implement \ n "if (strncmp (buf," Help ", 4) = = 0) {send_msg_to_client (client_id, helpstring);} else if (strncmp (buf, "list", 4) = = 0) {file* fp = fopen (FileName, "R"), if (fp = = NULL) {perror ("fopen error!"); return;} Else{address Addr;char Buf[max_data_size];int count = 1;while (fread (&addr, sizeof (Address), 1, fp) = = 1) {sprintf (buf , "%-5dname: '%s ', phone=%s,home_address=%s,age:%d\n ", Count, Addr.name, Addr.phone, addr.home_address,addr.age);// Send one record at a time send_msg_to_client (client_id, buf); count++;}} Fclose (FP);} else if (strncmp (buf, "name", 4) = = 0) {char name[max_name_length];strcpy (name, BUF + 5);p rintf ("name=%s\n", name); Char Pho Ne[max_phone_length];p hone[0] = ' + '; find_phone_with_name (name, phone); Char buf[max_data_size];if (strlen (phone) > 0) {sprintf (buf, "phone=%s\n", phone);} else{sprintf (buf, "No such name=%s\n", Name);} Send_msg_to_client (client_id, buf);} else if (strncmp (buf, "Phon", 4) = = 0) {char phone[max_phone_length];strcpy (phone, buf + 5);p rintf ("phone=%s\n", phone); Ch AR name[max_name_length];name[0] = ' + '; find_name_with_phone (name, phone); Char buf[max_data_size];if (strlen (name) > 0) {sprintf (buf, "name=%s\n", name);} else{sprintf (buf, "No such phone number=%s\n", phone); Send_msg_to_client (client_id, buf);} /* * In thread, cannot be placed in handle_request * (no reason found) */else{char temp[max_data_size];sprintf (temp, "unknowCommand:%s\n\ttry help\n ", buf); Send_msg_to_client (client_id, temp);}} /* * Guaranteed sigint,sigquit, can gracefully close connection */void sig_int (int signo) {printf ("\nclose (%d) \nexit\n", SOCK_FD); close (SOCK_FD); _exit (0);} /* * Send message to CLIENT_FD */void* send_msg_to_client (int client_fd, char* msg) {assert (Msg!=null); if (Send (CLIENT_FD, MSG, Strlen (msg), 0) = =-1) {perror ("send error \ n");} return NULL;} /* * randomly generates n items */void generate_rand_n_address (int n) {address** addresses = (address**) malloc (sizeof (address*) * n); t i = 0; I < n; i++) {Addresses[i] = (address*) malloc (Address); Generate_name (addresses[i]->name); Generate_phone ( Addresses[i]->phone); addresses[i]->age = rand ()% + 10;printf ("generate:name->%s\tphone->%s\tage=%d\ N ", Addresses[i]->name,addresses[i]->phone, Addresses[i]->age);} Write_address (addresses, n);//release space for (int i = 0; i < n; i++) free (addresses[i]); /* * Write array addresses,n address to file */bool write_address (address* addresses[], int n) {file* fp = fopen (fIlename, "a"), if (fp = = NULL) {perror ("fopen error!\n"); exit (1);} else{for (int i = 0; i < n; i++) if (fwrite (Addresses[i], sizeof (Address), 1, FP) < 0) {perror ("fwrite error!\n"); exit (1);}} Fclose (FP); return 1;} /* * Find name with phone number phone */bool find_name_with_phone (char* name, char* phone) {assert (name!=null); assert (Phone!=null); file* fp = fopen (FileName, "R"), if (fp = = NULL) {perror ("fopen error!\n"); return 0;} Else{address Addr;while (fread (char*) &addr, sizeof (Address), 1, fp) = = 1) {if (strcmp (addr.phone, phone) = = 0) {strcpy (name, addr.name); return 1;}}} return 0;} /* * The first name in the returned file of the phone * succeeds, the phone is the result and returns 1, otherwise returns 0,phone */bool find_phone_with_name (char* name, char* phone) {assert ( Name!=null); assert (Phone!=null); file* fp = fopen (FileName, "R"), if (fp = = NULL) {perror ("fopen error!\n"); return 0;} Else{address Addr;while (fread (char*) &addr, sizeof (Address), 1, fp) = = 1) {if (strcmp (addr.name, name) = = 0) {strcpy (P Hone, Addr.phone); return 1;}}} return 0;} /* * Output all contacts of the file (if any) to standard output */VOID print_addresses () {file* fp = fopen (FileName, "R"), if (fp = = NULL) {perror ("fopen error!"); return;} Else{address addr;int count = 1;while (fread (&addr, sizeof (Address), 1, fp) = = 1) {printf ("%-5dname: '%s ', phone=%s, Home_address=%s,age:%d\n ", Count,addr.name, Addr.phone, addr.home_address, addr.age); count++;}} Fclose (FP);} /* * Randomly generate a string length less than max_name_length */char* alphabet = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; void Generate_name (char* name) {int len = rand ()% max_name_length;if (Len < 5) {len + 5;} for (int i = 0; i < len; i++) {Name[i] = Alphabet[rand ()% (sizeof (alphabet))];} Name[len] = ' + ';} /* Generates a 11-digit phone number = "0123456789", void Generate_phone (char* phone) {phone[0] = ' 1 '; for (int i = 1; i < */char*; I + +) {Phone[i] = Number[rand ()% 10];} PHONE[11] = ' + ';//end} #endif//
Client
/* * Run command *g++ client.cpp-o client &&./client 192.168.111.139#serverip */#ifndef client#define Client#inc lude<sys/select.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include < string.h> #include <netdb.h> #include <sys/types.h> #include <unistd.h> #include <pthread.h > #include <arpa/inet.h> #include <netinet/in.h> #include <signal.h> #include <sys/socket.h >const int servport = 5555;const int max_data_size = 1000;//per maximum data transfer//void* Send_msg_to_server (void* args); void* inte Ract_with_server (void* agrs), void sig_int (int signo), static int sockfd = -1;int main (int argc, char* argv[]) {if (Signal (SI GINT, sig_int) = = Sig_err) {perror ("signal (Sigint,sig_int)");} if (Signal (sigquit, sig_int) = = Sig_err) {perror ("signal (Sigquit,sig_int)");} if (ARGC < 2) {printf ("Please enter Server IP\n"); exit (1);} char* ServerIP = argv[1];struct sockaddr_in serv_addr;serv_addr.sin_family = Af_inet;serv_addr.sin_port = Htons ( Servport); serv_ADDR.SIN_ADDR.S_ADDR = inet_addr (ServerIP);//* ((struct in_addr*) host->h_addr);p rintf ("serverip:%s\n", Inet_ntoa (SERV_ADDR.SIN_ADDR)); Bzero (& (Serv_addr.sin_zero), 8); int Recvbytes;char buf[max_data_size];if (SOCKFD = socket (af_inet, sock_stream, 0 ) = =-1) {perror ("Socket creation Error! "); exit (1);} if (Connect (sockfd, struct sockaddr*) &serv_addr, sizeof (serv_addr)) = =-1) {perror ("Connect Error! "); sleep (1);} if (SOCKFD < 0) {return NULL;} For Selectfd_set Readset; Fd_zero (&readset); Fd_set (Sockfd,&readset);//fd_set (stdin_fileno,&readset); int Reseivebytes;//char Buf[MAX_DATA_SIZE];while (1) {Fd_set readset_temp;readset_temp = readset;//receive data once using 1s timeval tvptr;tvptr.tv_sec = 1;tvptr.tv_usec = 0;bool flag_ recived = 0;int Rs;while ((rs = select (SOCKFD + 1, &readset_temp, NULL, NULL, &TVPTR)) > 0) {flag_recived = 1;// Recv Ready if ((Reseivebytes = recv (SOCKFD, buf, max_data_size, 0)) = =-1) {perror ("recv error!\n"); exit (1);} else if (reseivebytes > 0) {buf[reseivebytes] = '% ';p riNTF ("Received msg from server:\n%s\n", buf);} else if (Reseivebytes < 0) {//Connection disconnected printf ("close (%d) \ n", SOCKFD); close (SOCKFD); return NULL;} memset (buf, 0, max_data_size);//readset_temp restore readset_temp = readset;} if (Rs < 0) {perror ("select!");} /* * No recv not required to output hint *///if (flag_recived==1) printf ("Input cmd sended to server-->"),/* * Read a line (containing ' \ n ' at the end), remove ' \ n ' = ' /fgets (buf, Max_data_size, stdin);/* * Blank line does not send */if (strlen (BUF) > 1) {buf[strlen (BUF)-1] = ' + '; if (strncmp (buf, "Shel" , 4) = = 0) {System (BUF + 5);} else if (send (SOCKFD, buf, strlen (BUF), 0) = =-1) {perror ("Send Error!\n");} if (strncmp (buf, "Quit", 4) = = 0) {close (SOCKFD); exit (0);}} Close (SOCKFD); return 0;} void Sig_int (int signo) {printf ("\nclose (%d) \ n", SOCKFD); close (SOCKFD); _exit (0);} #endif
Simple Client/server using the Linux Berkeley Socket implementation Editor