Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
360 | f9daq | 1 | /* |
2 | C socket server example, handles multiple clients using threads */ |
||
3 | |||
4 | #include<stdio.h> |
||
5 | #include<string.h> //strlen |
||
6 | #include<stdlib.h> //strlen |
||
7 | #include<sys/socket.h> |
||
8 | #include<arpa/inet.h> //inet_addr |
||
9 | #include<unistd.h> |
||
10 | #//write |
||
11 | #include<pthread.h> |
||
12 | #include "daq.h" |
||
13 | #define PORT 9930 |
||
14 | //the thread function |
||
15 | |||
16 | |||
17 | |||
18 | void *connection_handler(void *); |
||
19 | |||
20 | int is_connected = 0; |
||
21 | int ncalls=0; |
||
22 | extern int ctrl_c; |
||
23 | |||
24 | int writesock(int sock, int id , char *msg, int len ){ |
||
25 | int hdr[2]; |
||
26 | hdr[0]= id; |
||
27 | hdr[1]= len + 8; |
||
28 | write(sock , hdr , 8); |
||
29 | return write(sock , msg , len); |
||
30 | } |
||
31 | |||
32 | |||
33 | int main(int argc , char *argv[]) { |
||
34 | int socket_desc , client_sock , c , *new_sock=NULL; |
||
35 | struct sockaddr_in server , client; |
||
36 | |||
37 | if (argc >1) return daq_main(argc, argv); |
||
38 | |||
39 | //Create socket |
||
40 | socket_desc = socket(AF_INET , SOCK_STREAM , 0); |
||
41 | if (socket_desc == -1) |
||
42 | { |
||
43 | printf("Could not create socket"); |
||
44 | } |
||
45 | puts("Socket created"); |
||
46 | |||
47 | //Prepare the sockaddr_in structure |
||
48 | server.sin_family = AF_INET; |
||
49 | server.sin_addr.s_addr = INADDR_ANY; |
||
50 | server.sin_port = htons( PORT ); |
||
51 | |||
52 | //Bind |
||
53 | if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) |
||
54 | { |
||
55 | //print the error message |
||
56 | perror("bind failed. Error"); |
||
57 | return 1; |
||
58 | } |
||
59 | puts("bind done"); |
||
60 | |||
61 | //Listen |
||
62 | listen(socket_desc , 3); |
||
63 | |||
64 | //Accept and incoming connection |
||
65 | puts("Waiting for incoming connections..."); |
||
66 | c = sizeof(struct sockaddr_in); |
||
67 | |||
68 | |||
69 | //Accept and incoming connection |
||
70 | puts("Waiting for incoming connections..."); |
||
71 | c = sizeof(struct sockaddr_in); |
||
72 | while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) |
||
73 | { |
||
74 | puts("Connection accepted"); |
||
75 | |||
76 | pthread_t sniffer_thread; |
||
77 | |||
78 | if (is_connected){ |
||
79 | char message[0xFF]="Only one client can connect. Disconnect it first!"; |
||
80 | perror(message); |
||
81 | writesock(client_sock , 0, message , strlen(message)); |
||
82 | close (client_sock); |
||
83 | continue; |
||
84 | } |
||
85 | new_sock = (int *) malloc(1); |
||
86 | *new_sock = client_sock; |
||
87 | if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0) |
||
88 | { |
||
89 | perror("could not create thread"); |
||
90 | return 1; |
||
91 | } |
||
92 | |||
93 | |||
94 | //Now join the thread , so that we dont terminate before the thread |
||
95 | //pthread_join( sniffer_thread , NULL); |
||
96 | |||
97 | puts("Handler assigned"); |
||
98 | |||
99 | } |
||
100 | |||
101 | if (client_sock < 0) |
||
102 | { |
||
103 | perror("accept failed"); |
||
104 | return 1; |
||
105 | } |
||
106 | |||
107 | return 0; |
||
108 | } |
||
109 | |||
110 | |||
111 | |||
112 | void *daq_handler(void *rdata){ |
||
113 | |||
114 | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); |
||
115 | //Get the socket descriptor |
||
116 | int sock = *(int*)rdata; |
||
117 | int *idata = (int *)rdata; |
||
118 | |||
119 | char * settings = (char *) (idata+2); |
||
120 | daq_init(settings); |
||
121 | settings +=12; |
||
122 | int bufsize = 0; |
||
123 | char * data = NULL; |
||
124 | |||
125 | //for(int i =0;i<5;i++) printf("%d %d\n",i, idata[i]); |
||
126 | while (1){ |
||
127 | int nb = daq_run ( settings, &data, &bufsize ); |
||
128 | int error = 0; |
||
129 | socklen_t len = sizeof (error); |
||
130 | int retval = getsockopt (sock, SOL_SOCKET, SO_ERROR, &error, &len); |
||
131 | if (retval!=0 || error!=0) break; |
||
132 | writesock(sock , 1, data , nb ); |
||
133 | if (ctrl_c) break; |
||
134 | //break; |
||
135 | } |
||
136 | if (data!=NULL) free(data); |
||
137 | fprintf(stderr, "Exiting thread %d\n", sock ) ; |
||
138 | return NULL; |
||
139 | } |
||
140 | |||
141 | /* |
||
142 | * This will handle connection for each client |
||
143 | * */ |
||
144 | |||
145 | void *connection_handler(void *socket_desc) { |
||
146 | //Get the socket descriptor |
||
147 | int sock = *(int*)socket_desc; |
||
148 | int read_size; |
||
149 | char *message , client_message[2000]; |
||
150 | is_connected = 1; |
||
151 | //Send some messages to the client |
||
152 | message = "Info from connection handler\n"; |
||
153 | writesock(sock , 0, message , strlen(message)); |
||
154 | |||
155 | //Receive a message from client |
||
156 | pthread_t daq_thread = 0; |
||
157 | |||
158 | while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 ) |
||
159 | { |
||
160 | //Send the message back to client |
||
161 | int * hdr = (int *) client_message; |
||
162 | printf("Received %d bytes RECID = %d LEN %d\n",read_size, hdr[0], hdr[1]); |
||
163 | switch (hdr[0]){ |
||
164 | case 0: |
||
165 | ctrl_c = 0; |
||
166 | hdr[0]= sock; |
||
167 | if( pthread_create( &daq_thread , NULL , daq_handler , (void*) &client_message) < 0) |
||
168 | { |
||
169 | perror("could not create daq thread"); |
||
170 | } |
||
171 | break; |
||
172 | case 1: |
||
173 | ctrl_c = 1; |
||
174 | sleep(1); |
||
175 | if (daq_thread) { |
||
176 | pthread_cancel(daq_thread); |
||
177 | daq_thread = 0; |
||
178 | } |
||
179 | |||
180 | break; |
||
181 | default: break; |
||
182 | |||
183 | } |
||
184 | } |
||
185 | |||
186 | if(read_size == 0) |
||
187 | { |
||
188 | puts("Client disconnected"); |
||
189 | fflush(stdout); |
||
190 | } |
||
191 | else if(read_size == -1) |
||
192 | { |
||
193 | perror("recv failed"); |
||
194 | |||
195 | } |
||
196 | if (daq_thread) { |
||
197 | pthread_cancel(daq_thread); |
||
198 | daq_thread = 0; |
||
199 | } |
||
200 | |||
201 | |||
202 | //Free the socket pointer |
||
203 | free(socket_desc); |
||
204 | socket_desc = 0; |
||
205 | is_connected = 0; |
||
206 | |||
207 | return 0; |
||
208 | } |
||
209 |