Linux Network Programming--tcp Concurrent Server (multi-threaded)

Source: Internet
Author: User

TCP multi-threaded concurrent server
multithreaded servers are improvements to multi-process servers, because the multi-process server consumes large system resources when it creates the process, so instead of a process with threads, the service handlers can be created more quickly. According to statistics, creating a thread is 10,100 times times faster than creating a process , so the thread is called a "lightweight" process . A thread differs from a process in that all threads within a process share the same global memory, global variables, and so on, and this mechanism brings up synchronization problems.

TCP multi-threaded concurrent Server framework:



When we use multi-threaded concurrent servers, we use the above framework directly, and we only modify the contents of Client_fun (). code Example:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys /socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h>/**************** Function name: void *client_fun (void *arg) function function: Thread function, Handling Customer Information function parameters: Connected socket function return: no ************************************************************************/void *client_ Fun (void *arg) {int recv_len = 0;char recv_buf[1024] = "";//Receive buffer int CONNFD = (int) arg; Sent over connected sockets//Receive data while ((Recv_len = recv (CONNFD, Recv_buf, sizeof (RECV_BUF), 0)) > 0) {printf ("Recv_buf:%s\n", recv_ BUF); Print data Send (CONNFD, recv_buf, Recv_len, 0); Back to the client data}printf ("Client closed!\n"); Close (CONNFD);//close connected socket return NULL;} ===============================================================//syntax format: void main (void)//Implement function: main function, establish a TCP concurrent server/ /inlet parameter: none//export parameter: no//===============================================================int main (int argc, char *argv[]) { Int SOCKFD = 0;//socket int CONNFD = 0;int Err_log = 0;struct sockaddr_in my_addr;//server address structural body unsigned short port = 8080;   Listening Port pthread_t thread_id;printf ("TCP Server Started at Port%d!\n", port); SOCKFD = socket (af_inet, sock_stream, 0); Create a TCP socket if (SOCKFD < 0) {perror ("socket error"); exit (-1);}   Bzero (&my_addr, sizeof (MY_ADDR)); Initialize the server address my_addr.sin_family = Af_inet;my_addr.sin_port = htons (port); my_addr.sin_addr.s_addr = htonl (Inaddr_any); printf ("Binding Server to Port%d\n", port);//Bind Err_log = Bind (SOCKFD, (struct sockaddr*) &my_addr, sizeof (MY_ADDR)); if (Err_log! = 0) {perror ("bind"); Close (SOCKFD); exit (-1);} Listen, socket becomes passive Err_log = Listen (SOCKFD), if (err_log! = 0) {perror ("listen"); Close (SOCKFD); exit (-1);}   printf ("Waiting client...\n"); while (1) {char Cli_ip[inet_addrstrlen] = "";   Used to save client IP address struct sockaddr_in client_addr;   Used to save the client address socklen_t Cliaddr_len = sizeof (CLIENT_ADDR); The!!! must be initialized Get an already established connection CONNFD = accept (sockfd, struct sockaddr*) &client_addr, &AMp;cliaddr_len); if (CONNFD < 0) {perror ("Accept this Time"); continue;} Print the client's IP and Port inet_ntop (Af_inet, &client_addr.sin_addr, Cli_ip, Inet_addrstrlen);p rintf ("--------------------- -------------------------\ n ");p rintf (" Client ip=%s,port=%d\n ", Cli_ip,ntohs (Client_addr.sin_port)); if (Connfd > 0) {//Because all threads in the same process share memory and variables, special handling and value passing is required when passing parameters.  Pthread_create (&thread_id, NULL, (void *) Client_fun, (void *) CONNFD); Create thread Pthread_detach (thread_id); Thread separation, automatic recovery of resources at the end}}close (SOCKFD); return 0;}

Operation Result:

Note :
1. The last parameter of the Pthread_create () function above is the void * Type, why is it possible to pass the value connfd?
while (1) {int connfd = accept (SOCKFD, (struct sockaddr*) &client_addr, &cliaddr_len);p Thread_ Create (&thread_id, NULL, (void *) Client_fun, (void *) CONNFD);  Pthread_detach (thread_id); } 

because void * is 4 bytes, 4 bytes,


2. The last parameter of the Pthread_create () function above is can I pass an address? Yes, but it can cause unpredictable problems for the server

while (1) {int connfd = accept (sockfd, struct sockaddr*) & CLIENT_ADDR, &cliaddr_len);p thread_create (&thread_id, NULL, (void *) Client_fun, (void *) &CONNFD);  Pthread_detach (thread_id); 



2. If we want to pass more than one parameter to the thread function, we first consider that is the struct parameter , and then the value is not feasible, can only pass the address .

that's when we need to think about multitasking. Mutex or synchronization problem, here through Mutual exclusion Lock to solve this problem, make sure that the struct parameter value is saved by a temporary variable before it is allowed to be modified.

#include <pthread.h>    pthread_mutex_t mutexes;  Define mutex, global variable    pthread_mutex_init (&mutex, NULL),//Initialize mutex, mutex is open/locked by default,    before unlocking, Pthread_mutex_lock () Will block  Pthread_mutex_lock (&mutex);   int CONNFD = Accept (SOCKFD, (struct sockaddr*) &client_addr, &cliaddr_len);    Parameters passed to the callback function, &CONNFD, address pass  pthread_create (&thread_id, NULL, (void *) client_process, (void *) &CONNFD);  Create thread//    thread callback function  void *client_process (void *arg  )      {int CONNFD = * (int *) arg;//sent over connected socket            // Unlock, Pthread_mutex_lock () wake up, do not block      Pthread_mutex_unlock (&mutex);             return  NULL;  }  

Example code:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys /socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h>pthread_mutex_t mutex;//define mutex, global variable/************************************************************************ function name: void *client_ Process (void *arg) function function: thread function, handling client information function parameters: Connected socket function returned: no ************************************************************ /void *client_process (void *arg) {int recv_len = 0;char recv_buf[1024] = "";//Receive buffer int CONNFD = * (int *) arg; Sent over connected sockets//Unlock, Pthread_mutex_lock () wake-up, non-blocking pthread_mutex_unlock (&mutex); Receive data while ((Recv_len = recv (CONNFD, Recv_buf, sizeof (RECV_BUF), 0)) > 0) {printf ("Recv_buf:%s\n", recv_buf);//Print Data S End (CONNFD, Recv_buf, Recv_len, 0); Back to the client data}printf ("Client closed!\n"); Close (CONNFD);//close connected socket return NULL;} ===============================================================//syntax format: void main (void)//Implement function: main function, establish a TCP concurrent server/ /Entry Parameters: none//export parameter: no//===============================================================int main (int argc, char *argv[]) {int SOCKFD = 0;//socket int CONNFD = 0;int Err_log = 0;struct sockaddr_in my_addr;//server address structural body unsigned short port = 8080; Listening Port pthread_t thread_id;pthread_mutex_init (&mutex, NULL);   To initialize the mutex, the mutex is turned on by default to printf ("TCP Server Started at Port%d!\n", port), SOCKFD = socket (af_inet, sock_stream, 0); Create a TCP socket if (SOCKFD < 0) {perror ("socket error"); exit (-1);}   Bzero (&my_addr, sizeof (MY_ADDR)); Initialize the server address my_addr.sin_family = Af_inet;my_addr.sin_port = htons (port); my_addr.sin_addr.s_addr = htonl (Inaddr_any); printf ("Binding Server to Port%d\n", port);//Bind Err_log = Bind (SOCKFD, (struct sockaddr*) &my_addr, sizeof (MY_ADDR)); if (Err_log! = 0) {perror ("bind"); Close (SOCKFD); exit (-1);} Listen, socket becomes passive Err_log = Listen (SOCKFD), if (err_log! = 0) {perror ("listen"); Close (SOCKFD); exit (-1);}   printf ("Waiting client...\n"); while (1) {char Cli_ip[inet_addrstrlen] = ""; Used to save the client IP address of a struct SOCKaddr_in client_addr;   Used to save the client address socklen_t Cliaddr_len = sizeof (CLIENT_ADDR); The!!! must be initialized Locked, Pthread_mutex_lock () will block Pthread_mutex_lock (&mutex) before unlocking, and/or get an already established connection CONNFD = accept (SOCKFD, struct   sockaddr*) &client_addr, &cliaddr_len); if (CONNFD < 0) {perror ("Accept this Time"); continue;} Print the client's IP and Port inet_ntop (Af_inet, &client_addr.sin_addr, Cli_ip, Inet_addrstrlen);p rintf ("--------------------- -------------------------\ n ");p rintf (" Client ip=%s,port=%d\n ", Cli_ip,ntohs (Client_addr.sin_port)); if (Connfd >  0) {//parameter passed to callback function, &AMP;CONNFD, address pass pthread_create (&thread_id, NULL, (void *) client_process, (void *) &AMP;CONNFD); Create thread Pthread_detach (thread_id); Thread separation, automatic recovery of resources at the end}}close (SOCKFD); return 0;}


Operation Result:


Note : This mutex has a fatal effect on the operational efficiency of the server.
code Download:




Linux Network Programming--tcp Concurrent Server (multi-threaded)

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.