CODE: # include
Extern int errno;
Void workthread (struct sockaddr_in sin, int loopnum) { CLIENTPKG cLientPkg; Char SendMsg [257]; Char RecvMsg [257]; Int rc = 0, j, nReturn, nLen, bJump = 0; Int ii; For (ii = 1; ii <= loopnum; ii ++) { Printf ("ThreadId = % d, loopnum: % d \ n", (int) getpid (), ii ); Rc = socket (PF_INET, SOCK_STREAM, 0 ); If (rc <0) { Printf ("Build socket Err: % d, % s! \ N ", errno, strerror (errno )); Exit (0 ); }
If (connect (rc, (struct sockaddr *) & sin, sizeof (sin ))! = 0) { Printf ("connect fail! \ N "); Exit (0 ); } Memset (& cLientPkg, 0, sizeof (cLientPkg )); Memcpy (cLientPkg. pPID, "0000", 4 ); CLientPkg. cCommand = 0x66; Memcpy (cLientPkg. pAreaID, "0000", 4 ); Memcpy (cLientPkg. Fig, "0000", 4 ); Memcpy (cLientPkg. pOperater, "00000", 5 ); Memcpy (cLientPkg. pMachID, "0121000100", 10 ); Memcpy (cLientPkg. pQueryStart, "20030801", 8 ); Memcpy (cLientPkg. pQueryEnd, "20031010", 8 ); Memcpy (SendMsg, & cLientPkg, sizeof (cLientPkg )); If (send (rc, SendMsg, 256, 0) <0) { Printf ("Send Message fail. \ n "); Exit (0 ); } Do { NLen = 0; Do { NReturn = recv (rc, RecvMsg + nLen, 256-nLen, 0 ); If (nReturn <0) { Printf ("Recv errno = % d \ n", errno ); Close (rc ); Exit (0 ); } NLen + = nReturn; } While (RecvMsg [6]! = (Char) 0xff ); If (RecvMsg [6]! = (Char) 0xff) { BJump = 1; } Else { BJump = 0; } } While (bJump = 1 ); Close (rc ); } }
Main (int argc, char * argv []) { Char strAdd [16]; Struct sockaddr_in sin; Int port = 9998; Int kk, ii; Int forknum = 10, loopnum = 10;
System ("clear "); Memset (strAdd, 0, 16 ); Memcpy (strAdd, "192.168.1.197", 13 ); Bzero (char *) & sin, sizeof (sin )); Sin. sin_family = AF_INET; Sin. sin_addr.s_addr = inet_addr (strAdd ); Sin. sin_port = htons (port );
If (argc> = 2) forknum = atoi (argv [1]); If (argc> = 3) loopnum = atoi (argv [2]);
For (kk = 1; kk <= forknum; kk ++) { Printf ("kk: % d \ n", kk ); If (fork () = 0) { Workthread (sin, loopnum ); Exit (0 ); } } Return; }
The source code for the server to process Client requests is as follows:
# Include
Extern CT MainCt; Extern int errno; Pthread_cond_t tcn_th_cond = PTHREAD_COND_INITIALIZER; Pthread_key_t p_key; // not used Struct tcn_thread_mgr * tcn_th_mgr = NULL;
Int TreadClntrequest (struct tcn_thread_data * data) { Int socket; BYTE RecvRecMessage [HOSTMSGLEN + 1]; Int nRet;
// Socket = pthread_getspecific (p_key ); Socket = data-> sock;
Memset (RecvRecMessage, 0, MSGLEN + 1 );
LogMessage ("run TreadClntrequest: socket = % d", socket ); NRet = recv (socket, RecvRecMessage, sizeof (CLIENTPKG), 0 ); If (nRet! = Sizeof (CLIENTPKG )) { LogMessage ("recv error! Errno = % d, errMsg: % s. ", errno, strerror (errno )); } Else { RecvRecMessage [6] = (char) 0xFF; SendDataToClient (socket, RecvRecMessage, MAINPACK, MainCt. TraceData ); }
Close (socket ); LogMessage ("TreadClntrequest finish! "); Return EXECOK; }
// All signals are blocked during thread execution. Void thread_signal_init () { Sigset_t thread_sigmask; Int rc;
If (rc = sigfillset (& thread_sigmask ))) { Pthread_exit (NULL ); }
If (rc = pthread_sigmask (SIG_BLOCK, & thread_sigmask, NULL ))) { Pthread_exit (NULL ); } }
Void * apctclnt_thread_run (void * args) { LogMessage ("run apctclnt_thread_run "); Struct tcn_thread_data * data = (struct tcn_thread_data *) args; Thread_signal_init ();
// Pthread_setspecific (p_key, args ); Data-> thread_id = pthread_self (); TreadClntrequest (data );
Pthread_mutex_lock (& (tcn_th_mgr-> lock )); If (tcn_th_mgr-> num_active_threads> = tcn_th_mgr-> max_threads) { LogMessage ("call pthread_cond_signal "); Pthread_cond_signal (& tcn_th_cond ); }
Tcn_th_mgr-> num_active_threads --;
Data-> thread_id = THREAD_NULL; Pthread_mutex_unlock (& (tcn_th_mgr-> lock ));
LogMessage ("apctclnt_thread_run thread exit! "); Pthread_exit (NULL );
Return NULL; }
Int acptclnt_thread_create (int socket) { Int rc; Pthread_t pTreateClnt; Pthread_attr_t; Int stacksize; Int thread_num; Stacksize = 1024;
Pthread_attr_init (& ); Pthread_attr_setdetachstate (& a, PTHREAD_CREATE_DETACHED); // PTHREAD _ CREATE_JOINABLE Pthread_attr_setstacksize (& a, stacksize ); LogMessage ("acptclnt_thread_create socket = % d", socket );
Pthread_mutex_lock (& tcn_th_mgr-> lock );
While (tcn_th_mgr-> num_active_threads> = tcn_th_mgr-> max_threads) { LogMessage ("call pthread_cond_wait "); Pthread_cond_wait (& tcn_th_cond, & tcn_th_mgr-> lock ); } /* Search for an open slot to store the thread data in */ For (thread_num = 0; thread_num <tcn_th_mgr-> max_threads; thread_num ++) { If (tcn_th_mgr-> thread_data [thread_num]. thread_id = THREAD_NULL) Break; }
Tcn_th_mgr-> thread_data [thread_num]. sock = socket;
Rc = pthread_create (& tcn_th_mgr-> thread_data [thread_num]. thread_id, & A, apctclnt_thread_run, (void *) (& (tcn_th_mgr-> thread_data [thread_num]); // Rc = pthread_create (& pTreateClnt, & a, apctclnt_thread_run, (void *) socket ); If (rc! = 0) { LogMessage ("AcptClnt: create thread fail! Rc = % d, errMsg: % s. ", rc, strerror (rc )); Close (socket ); } Else { LogMessage ("create thread: apctclnt_thread_run OK ."); Tcn_th_mgr-> num_active_threads ++; }
Pthread_mutex_unlock (& tcn_th_mgr-> lock );
Pthread_attr_destroy (& ); Return EXECOK; }
Struct sigaction acptclnt_sa_int;
Void acptclnt_signal_chld (int signal) { Int stat; LogMessage ("do acptclnt_signal_chld ");
Wait3 (NULL, WNOHANG, NULL ); /* While (waitpid (-1, & stat, WNOHANG)> 0) { LogMessage ("have kill a child "); } */ Return; }
Int acptclnt_threads_init () { Pthread_key_create (& p_key, NULL ); Tcn_th_mgr = calloc (1, sizeof (struct tcn_thread_mgr )); If (tcn_th_mgr = NULL) { Return EXECFAIL; } Else { Tcn_th_mgr-> max_threads = MainCt. MaxThreadNum; Tcn_th_mgr-> thread_data = calloc (tcn_th_mgr-> max_threads, sizeof (struct tcn_thread_data )); If (tcn_th_mgr-> thread_data = NULL) { Free (tcn_th_mgr ); Return EXECFAIL; } Pthread_mutex_init (& tcn_th_mgr-> lock, NULL ); Tcn_th_mgr-> num_active_threads = 0; } Return EXECOK; }
Void acptclnt_destroy () { If (tcn_th_mgr) { Pthread_mutex_destroy (& tcn_th_mgr-> lock );
If (tcn_th_mgr-> thread_data) Free (tcn_th_mgr-> thread_data );
Free (tcn_th_mgr ); } }
Int acptclnt_signal_init () { Sigset_t sigmask;
Sigemptyset (& sigmask ); If (sigaddset (& sigmask, SIGCHLD )) { LogMessage ("sigaddset: % s", strerror (errno )); Return EXECFAIL; }
If (pthread_sigmask (SIG_UNBLOCK, & sigmask, NULL )) { LogMessage ("Setting thread signal mask: % s", strerror (errno )); Return EXECFAIL; }
Acptclnt_sa_int.sa_handler = acptclnt_signal_chld; If (sigaction (SIGCHLD, & acptclnt_sa_int, NULL )) { LogMessage ("signal SIGCHLD not registered: % s", strerror (errno )); Return EXECFAIL; }
Return EXECOK; }
/* Function: receives the processing program. */ Void * AcptClnt () { Struct sockaddr_in rstLclAddr; Struct sockaddr_in tcp_addr; Int wAddrLen; Socklen_t clilen; Int sockfd, accsockfd; If (acptclnt_threads_init ()! = EXECOK) { Pthread_exit (NULL ); }
If (acptclnt_signal_init ()! = EXECOK) { Acptclnt_destroy (); Pthread_exit (NULL ); } WAddrLen = sizeof (rstLclAddr ); Sockfd = socket (AF_INET, SOCK_STREAM, 0 ); If (sockfd <0) { LogMessage ("AcptClnt: Create Socket error! Errno = % d, errMsg: % s. ", errno, strerror (errno )); Acptclnt_destroy (); Pthread_exit (NULL ); } Else { LogMessage ("AcptClnt: Create Socket OK! Socket = % d ", sockfd ); } RstLclAddr. sin_family = AF_INET; // "Internet" Address Family RstLclAddr. sin_addr.s_addr = inet_addr (MainCt. HostAddr); // Local IP address RstLclAddr. sin_port = htons (MainCt. ClientPort); // Set to "Echo" Port If (bind (sockfd, (struct sockaddr *) & rstLclAddr, wAddrLen) <0) { LogMessage ("AcptClnt: Socket Bind error! IP: % s, Port: % d. errno = % d, errMsg: % s .",\ MainCt. HostAddr, MainCt. ClientPort, errno, strerror (errno )); Acptclnt_destroy (); Pthread_exit (NULL ); }
If (listen (FIG, 100) <0) { LogMessage ("AcptClnt: Socket Listen error! Errno = % d, errMsg: % s. ", errno, strerror (errno )); Acptclnt_destroy (); Pthread_exit (NULL ); }
LogMessage ("AcptClnt Progress: Start Success! ");
For (;;) { Accsockfd = accept (sockfd, (struct sockaddr *) & tcp_addr, & clilen ); If (accsockfd <0) { LogMessage ("AcptClnt: Socket Accept failed! Errno = % d, errMsg: % s. ", errno, strerror (errno )); } Else { LogMessage ("AcptClnt: Accepted Client_Request... socket = % d", accsockfd ); Acptclnt_thread_create (accsockfd ); } Continue; } } |