Linux is based on multi-threaded server/customer-side chat program, using blocking socket technology, and multithreading technology implementation.
Client Side program: CLIENT.C
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <unistd.h> #include < errno.h> #include <pthread.h> #define buffsize 1024#define errorcode-1static void *thread_send (void *arg) {Char Buf[buffsize];int SD = * (int *) Arg;while (1) {memset (buf, 0, sizeof (BUF)); Read (Stdin_fileno, buf, sizeof (BUF)); if (Send (S D, buf, strlen (BUF), 0) = =-1) {printf ("Send error:%s \ n", Strerror (errno)); return NULL;} Static void* thread_recv (void *arg) {char buf[buffsize];int SD = * (int *) Arg;while (1) {memset (buf, 0, sizeof (BUF)); int RV = recv (SD, buf, sizeof (BUF), 0), if (rv <= 0) {if (rv = = 0)//server socket shutdown Condition {printf ("Server has already full!\n"); Exi T (0);//exit the entire customer service end}printf ("recv error:%s \ n", Strerror (errno)); printf ("%s", buf);//output received}return NULL;} int run_client (char *ip_str, int port) {int Client_sd;int con_rv;pthread_t thrd1, Thrd2;struCT sockaddr_in client_sockaddr; Define the IP address structure CLIENT_SD = socket (af_inet, sock_stream, 0), if (CLIENT_SD = =-1) {printf ("socket create error:%s \ n", Strerror (E Rrno)); return ERRORCODE;} memset (&client_sockaddr, 0, sizeof (CLIENT_SOCKADDR)); client_sockaddr.sin_port = htons (port); Specify a port number and transmit the hosts byte type to the INET type byte type (big or small end problem) client_sockaddr.sin_family = af_inet;//Set the structure type to Tcp/ipclient_sockaddr.sin _ADDR.S_ADDR = inet_addr (IP_STR);//Convert the IP address of the string to int, the IP address to be connected by the client CON_RV = connect (client_sd, struct sockaddr*) & Client_sockaddr,sizeof (CLIENT_SOCKADDR))//struct sockaddr is a long-defined struct sockaddr_in is later defined, currently used more// Call connect to connect to the specified IP address and port number, after establishing the connection via the socket descriptor to communicate if (CON_RV = =-1) {printf ("Connect error:%s \ n", Strerror (errno)); return ERRORCODE;} if (Pthread_create (&thrd1, NULL, Thread_send, &client_sd)! = 0) {printf ("thread error:%s \ n", Strerror (errno)); return ERRORCODE;} if (Pthread_create (&thrd2, NULL, THREAD_RECV, &client_sd)! = 0) {printf ("thread error:%s \ n", Strerror (errno)); return ERRORCODE;}pthread_join (THRD2, NULL);//wait for thread to exit Pthread_join (Thrd1, NULL); close (CLIENT_SD); return 0;} int main (int argc, char *argv[]) {if (ARGC < 3) {printf ("Usage:ip port,example:127.0.0.1 8080 \ n"); return ERRORCODE;} int port = atoi (Argv[2]), char *ip_str = argv[1];run_client (ip_str,port); return 0;}
Service-side program: SERVER.C
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <unistd.h> #include <errno.h> #include <pthread.h> #define maxconn 2#define errorcode-1#define Buffsize 1024int count_connect = 0;pthread_mutex_t Mutex = pthread_mutex_initializer;struct pthread_socket{ int socket_d; pthread_t thrd;}; static void *thread_send (void *arg) { char buf[buffsize]; int SD = * (int *) arg; memset (buf, 0, sizeof (BUF)); strcpy (buf, "Hello,welcome to you! \ n "); if (Send (SD, buf, strlen (BUF), 0) = =-1) { & nbsp;printf ("Send error:%s \ n", Strerror (errno)); return null; } while (1) &nBsp { memset (buf, 0, sizeof (BUF)); read ( Stdin_fileno, buf, sizeof (BUF)); if (Send (SD, buf, strlen (BUF), 0) = =-1) & nbsp { printf ("Send error:%s \ n", Strerror (errno)); break; } } return NULL;} Static void* thread_recv (void *arg) { char buf[buffsize]; struct pthread_socket *pt = (struct Pthread_socket *) arg; int sd = pt->socket_d; pthread_t THRD = pt->thr d; while (1) { memset (buf, 0, sizeof (BUF)), & nbsp; int RV = recv (SD, buf, sizeof (BUF), 0); is blocked &nBsp;if (RV < 0) { printf ("recv error:%s \ n", Strerror (errno)); break; } if (rv = = 0)//This situation indicates that the client has closed the socket connection & nbsp { break; } printf ("%s", buf); Output accepted to content } pthread_cancel (THRD); pthread_mutex_lock (& Mutex); count_connect--; pthread_mutex_unlock (&mutex); Close (SD); return NULL;} static int Create_listen (int port) { int listen_st; struct sockaddr_in sockaddr;// Define IP address structure int on = 1; listen_st = socket (af_INET, Sock_stream, 0); Initialize socket if (Listen_st = =-1) { printf (" Socket create error:%s \ n ", Strerror (errno)); return errorcode; } if (setsockopt (Listen_st, Sol_socket, so_reuseaddr, &on, sizeof (ON)) = =-1)//Set IP address re-usable and nbsp; { printf ("setsockopt error:%s \ n", Strerror (errno)); return errorcode; } sockaddr.sin_port = htons ( Port); Specify a port number and transmit the hosts byte type to the INET type byte type (big or small end problem) sockaddr.sin_family = af_inet; // Set the struct type to tcp/ip sockaddr.sin_addr.s_addr = htonl (inaddr_any); //The server is waiting for someone else to connect, No need to find who ip //here to write a long inaddr_any represents all IP on the server, this one server may have multiple IP addresses, because there may be multiple NICs if ( Bind (Listen_st, (struct sockaddr *) &sockaddr, sizeof (SockadDR) = =-1) { printf ("Bind error:%s \ n", Strerror (errno)); return errorcode; } if (Listen (Listen_st, 5 ) = =-1)// Server start monitoring { printf ("Listen error:%s \ n ", Strerror (errno)); return errorcode; } return listen_st;} int accept_socket (int listen_st) { int accept_st; struct sockaddr_in accept_ sockaddr; Define the Accept IP address structure socklen_t addrlen = sizeof (ACCEPT_SOCKADDR); memset (& ACCEPT_SOCKADDR, 0, addrlen); accept_st = Accept (Listen_st, (struct sockaddr*) &accept_sockaddr, &addrlen); //accept will block until the client connects. Service side This socket is only responsible for listen is not a customer service connection came over //is to return socket communication via accept if (Accept_st = =-1) { printf ("Accept error:%s \ n", Strerror (errno)); return errorcode; } printf ("Accpet ip:%s \ n", Inet_ntoa (ACCEPT_SOCKADDR.SIN_ADDR)); return accept_st;} int run_server (int port) { int Listen_st = Create_listen (port); //Create listener socket pthread_t send_thrd, recv_thrd; struct pthread_socket ps; int accept_ st; if (Listen_st = =-1) { return errorcode;& nbsp; } printf ("server start \ n"); while (1) { accept_st = Accept_socket (Listen_st); Get Connected socket if (Accept_st = =-1) &nbsP { return errorcode; } if (count_connect >= maxconn) {& nbsp; printf ("Connect has already be full! \ n "); close (accept_st); continue; } Pthread_mutex_lock (&mutex); count_connect++; pthread_mutex_unlock (&mutex); if (pthread_create (&send_ THRD, NULL, Thread_send, &accept_st)! = 0)//Create Send message thread { printf ("Create thread error:%s \ n", Strerror (errno)); &NBSP;&NBsp; break; } pthread_detach (SEND_THRD); //set thread decoupling so the main thread doesn't have to join ps.socket_d = accept_st; ps.thrd = send_thrd; if (Pthread_create (&RECV_THRD, NULL, THREAD_RECV, &ps)! = 0)//create receive Message thread & nbsp { printf ("Create thread error:%s \ n" , Strerror (errno)); break; } pthread_detach (RECV_THRD); Set the thread to be separable, so that you don't have to pthread_join } close (accept_st); close ( Listen_st); return 0;} Server Mainint Main (int argc, char *argv[]) { if (argc < 2) &nBsp { printf ("usage:port,example:8080 \ n"); return-1; } int port = atoi (argv[1]); if (port = = 0) & nbsp { printf ("Port error! \ n "); } else { run_server (port); } return 0;}
Makefile file
. suffixes:.c. OCC = gccSRCS1 = CLIENT.CSRCS2 = SERVER.COBJS1 = $ (SRCS1:.C=.O) OBJS2 = $ (srcs2:.c=.o) EXEC1 = clientEXEC2 = SE rverstart:$ (OBJS1) $ (OBJS2) $ (CC)-g-o $ (EXEC1) $ (OBJS1)-lpthread$ (CC)-g-o $ (EXEC2) $ (OBJS2)-lpthread.c.o:$ (cc)-g-o [Email protected]-C $<clean:rm-f $ (OBJS1) Rm-f $ (OBJS2)
Compiling and running the server
Server/Customer service-side implementation of transceiver
Connect via Telnet on Windows
Here 172.19.198.109 is the IP address of my server
Linux based on multi-threaded server/customer-side Chat program source code