1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <arpa/inet.h> #include <fcntl.h> #include <unistd.h> #include <pthread.h> #define PORT 1539 #define MAX_CLIENT 32 // connection information struct connectInfo { int socket; int index; }; // pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_t tid[MAX_CLIENT]={0}; // Each connection creates a pthread to handle communication. void * sThread(void *arg) { char message[64], retmsg[64]; struct connectInfo *cInfo = (struct connectInfo *)arg; int nSocket = cInfo->socket; pthread_detach(pthread_self()); int resume=1, i; struct timeval timeout; fd_set fds; FD_ZERO(&fds); FD_SET(nSocket, &fds); while (resume) { // reset timer timeout.tv_sec = 300; timeout.tv_usec = 0; // receive message with timeout control. i = select(nSocket+1, &fds, NULL, NULL, &timeout); if (0 == i) { printf("[%d] timeout\n", nSocket); resume = 0; } else if (-1 == i) { printf("[%d] got error\n", nSocket); resume = 0; } else { // The message still needs to be retrieved by recv. recv(nSocket , message , sizeof(message) , 0); printf("[%d] got message %s\n", nSocket, message); //pthread_mutex_lock(&lock); /* */ //pthread_mutex_unlock(&lock); if (strncmp (message, "exit" , 4) == 0 ) { sprintf(retmsg, "bye"); resume = 0; } else { sprintf(retmsg, "I got %s", message); } // Reply message to the other side. send(nSocket, retmsg, sizeof(retmsg), 0); } } // close connection close(nSocket); // release tid tid[cInfo->index] = 0; // exit pthread pthread_exit(NULL); } int main(int argc, char *argv[]) { int sSocket, nSocket, i; struct sockaddr_in s_in; struct sockaddr_storage s_storage; socklen_t addr_size; struct connectInfo cInfo[MAX_CLIENT]; sSocket = socket(PF_INET, SOCK_STREAM, 0); // Set daemon to listen on port 1539 to any address s_in.sin_family = AF_INET; s_in.sin_port = htons(PORT); s_in.sin_addr.s_addr = htonl(INADDR_ANY); memset(s_in.sin_zero, '\0', sizeof s_in.sin_zero); bind(sSocket, (struct sockaddr *) &s_in, sizeof(s_in)); // start listen. if(listen(sSocket, MAX_CLIENT)==0) { printf("Listening\n"); } else { printf("Listen Fail\n"); exit(-1); } i = 0; while (1) { addr_size = sizeof(s_storage); nSocket = accept(sSocket, (struct sockaddr *) &s_storage, &addr_size); if (-1 == nSocket) { //accept return error continue; } // when got a new connection, find an empty tid to create a new pthread. for (i=0; i<MAX_CLIENT; i++) { if (0 == tid[i]) { cInfo.socket = nSocket; cInfo.index = i; if( pthread_create(&tid[i], NULL, sThread, (void*) &cInfo[i]) != 0 ) { printf("Failed to create thread\n"); } else { i = MAX_CLIENT+1; } } } if (MAX_CLIENT == i) { printf("No more free thread.\n"); close(nSocket); } } } |
2020/05/26
[C] Simple daemon example with multiple connections
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言