| 1,223 → 1,209 |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <arpa/inet.h> |
| /* |
| C socket server example, handles multiple clients using threads */ |
| |
| #include<stdio.h> |
| #include<string.h> //strlen |
| #include<stdlib.h> //strlen |
| #include<sys/socket.h> |
| #include<arpa/inet.h> //inet_addr |
| #include<unistd.h> |
| #//write |
| #include<pthread.h> |
| #include "daq.h" |
| /* #define DEBUG */ |
| |
| #define PORT 9930 |
| #define EXIT_FAILURE 1 |
| //the thread function |
| |
| int make_socket (port) |
| unsigned short int port; |
| { |
| int sock; |
| struct sockaddr_in name; |
| |
| /* create the socket. */ |
| sock = socket (AF_INET, SOCK_STREAM, 0); |
| if (sock < 0) |
| { |
| perror ("socket"); |
| exit (EXIT_FAILURE); |
| } |
| /* give the socket name */ |
| name.sin_family = AF_INET; |
| name.sin_port = htons (port); |
| name.sin_addr.s_addr = htonl (INADDR_ANY); |
| if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) |
| { |
| perror ("bind"); |
| exit (EXIT_FAILURE); |
| } |
| return sock; |
| |
| void *connection_handler(void *); |
| |
| int is_connected = 0; |
| int ncalls=0; |
| extern int ctrl_c; |
| |
| int writesock(int sock, int id , char *msg, int len ){ |
| int hdr[2]; |
| hdr[0]= id; |
| hdr[1]= len + 8; |
| write(sock , hdr , 8); |
| return write(sock , msg , len); |
| } |
| |
| void write_socket (sock_num, buff, len) |
| int sock_num, len; |
| char *buff; |
| { |
| int status; |
| |
| do |
| { |
| if (0 > (status = write (sock_num, buff, len))) |
| int main(int argc , char *argv[]) { |
| int socket_desc , client_sock , c , *new_sock=NULL; |
| struct sockaddr_in server , client; |
| |
| if (argc >1) return daq_main(argc, argv); |
| |
| //Create socket |
| socket_desc = socket(AF_INET , SOCK_STREAM , 0); |
| if (socket_desc == -1) |
| { |
| perror ("\nwrite(write_socket)"); |
| exit (EXIT_FAILURE); |
| printf("Could not create socket"); |
| } |
| len -= status; |
| buff += status; |
| } |
| while (len); |
| } |
| puts("Socket created"); |
| |
| //Prepare the sockaddr_in structure |
| server.sin_family = AF_INET; |
| server.sin_addr.s_addr = INADDR_ANY; |
| server.sin_port = htons( PORT ); |
| |
| //Bind |
| if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) |
| { |
| //print the error message |
| perror("bind failed. Error"); |
| return 1; |
| } |
| puts("bind done"); |
| |
| //Listen |
| listen(socket_desc , 3); |
| |
| //Accept and incoming connection |
| puts("Waiting for incoming connections..."); |
| c = sizeof(struct sockaddr_in); |
| |
| |
| //Accept and incoming connection |
| puts("Waiting for incoming connections..."); |
| c = sizeof(struct sockaddr_in); |
| while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) |
| { |
| puts("Connection accepted"); |
| |
| pthread_t sniffer_thread; |
| |
| void read_socket (sock_num, buff, len) |
| int sock_num, len; |
| char *buff; |
| { |
| int status; |
| if (is_connected){ |
| char message[0xFF]="Only one client can connect. Disconnect it first!"; |
| perror(message); |
| writesock(client_sock , 0, message , strlen(message)); |
| close (client_sock); |
| continue; |
| } |
| new_sock = (int *) malloc(1); |
| *new_sock = client_sock; |
| if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0) |
| { |
| perror("could not create thread"); |
| return 1; |
| } |
| |
| do |
| { |
| if (0 > (status = read (sock_num, buff, len))) |
| |
| //Now join the thread , so that we dont terminate before the thread |
| //pthread_join( sniffer_thread , NULL); |
| |
| puts("Handler assigned"); |
| |
| } |
| |
| if (client_sock < 0) |
| { |
| perror ("\nread(read_socket)"); |
| exit (EXIT_FAILURE); |
| perror("accept failed"); |
| return 1; |
| } |
| len -= status; |
| buff += status; |
| } |
| while (len); |
| |
| return 0; |
| } |
| |
| |
| |
| |
| int main (int argc, char ** argv) |
| { |
| int sock_org, sock_cam, sock_new; |
| int bufsize = 10000000; |
| int recvdata[0xFF]; |
| char *data, status, connected = 0; |
| char msg; |
| |
| void *daq_handler(void *rdata){ |
| |
| if (argc >1) return daq_main(argc, argv); |
| pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); |
| //Get the socket descriptor |
| int sock = *(int*)rdata; |
| int *idata = (int *)rdata; |
| |
| char * settings = (char *) (idata+2); |
| daq_init(settings); |
| settings +=12; |
| int bufsize = 0; |
| char * data = NULL; |
| |
| data = malloc(sizeof(int) * bufsize); |
| int *idata = (int*)data; |
| |
| fd_set active_fd_set, read_fd_set; |
| struct sockaddr_in clientname; |
| size_t size; |
| //for(int i =0;i<5;i++) printf("%d %d\n",i, idata[i]); |
| while (1){ |
| int nb = daq_run ( settings, &data, &bufsize ); |
| int error = 0; |
| socklen_t len = sizeof (error); |
| int retval = getsockopt (sock, SOL_SOCKET, SO_ERROR, &error, &len); |
| if (retval!=0 || error!=0) break; |
| writesock(sock , 1, data , nb ); |
| if (ctrl_c) break; |
| //break; |
| } |
| if (data!=NULL) free(data); |
| fprintf(stderr, "Exiting thread %d\n", sock ) ; |
| return NULL; |
| } |
| |
| /* |
| * This will handle connection for each client |
| * */ |
| |
| /* map camac memory */ |
| //map_camac (); |
| void *connection_handler(void *socket_desc) { |
| //Get the socket descriptor |
| int sock = *(int*)socket_desc; |
| int read_size; |
| char *message , client_message[2000]; |
| is_connected = 1; |
| //Send some messages to the client |
| message = "Info from connection handler\n"; |
| writesock(sock , 0, message , strlen(message)); |
| |
| //Receive a message from client |
| pthread_t daq_thread = 0; |
| |
| /* Create the socket and set it up to accept connections */ |
| sock_org = make_socket (PORT); |
| if (listen (sock_org, 1) < 0) |
| { |
| perror ("listen"); |
| exit (EXIT_FAILURE); |
| } |
| /* Initialize the set of active sockets */ |
| FD_ZERO (&active_fd_set); |
| FD_SET (sock_org, &active_fd_set); |
| |
| while (1) |
| { |
| read_fd_set = active_fd_set; |
| if (select (32, &read_fd_set, 0, 0, 0) <0) |
| while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 ) |
| { |
| perror ("select"); |
| exit (EXIT_FAILURE); |
| } |
| if (FD_ISSET (sock_org, &read_fd_set)) |
| { |
| size = sizeof (clientname); |
| sock_new = accept (sock_org, (struct sockaddr *) &clientname, &size); |
| if (sock_new < 0) |
| { |
| perror ("accept"); |
| exit (EXIT_FAILURE); |
| } |
| fprintf (stderr, "Server: connect from host %s, port %hd.\n", |
| inet_ntoa (clientname.sin_addr), |
| ntohs (clientname.sin_port)); |
| if (connected) |
| { |
| msg = 0; |
| status = send (sock_new, &msg, 1, 0); |
| { |
| perror ("send"); |
| exit (EXIT_FAILURE); |
| } |
| close (sock_new); |
| } |
| else |
| { |
| msg = 1; |
| status = send (sock_new, &msg, 1, 0); |
| if (status < 0) |
| //Send the message back to client |
| int * hdr = (int *) client_message; |
| printf("Received %d bytes RECID = %d LEN %d\n",read_size, hdr[0], hdr[1]); |
| switch (hdr[0]){ |
| case 0: |
| ctrl_c = 0; |
| hdr[0]= sock; |
| if( pthread_create( &daq_thread , NULL , daq_handler , (void*) &client_message) < 0) |
| { |
| perror("could not create daq thread"); |
| } |
| break; |
| case 1: |
| ctrl_c = 1; |
| sleep(1); |
| if (daq_thread) { |
| pthread_cancel(daq_thread); |
| daq_thread = 0; |
| } |
| |
| break; |
| default: break; |
| |
| { |
| perror ("send"); |
| exit (EXIT_FAILURE); |
| } |
| sock_cam = sock_new; |
| FD_SET (sock_cam, &active_fd_set); |
| connected = 1; |
| } |
| } |
| else |
| |
| if(read_size == 0) |
| { |
| /* Data ariving on an already-connected socket. */ |
| status = recv (sock_cam, &msg, 1, 0); |
| if (status < 0) |
| { |
| perror ("recv"); |
| exit (EXIT_FAILURE); |
| } |
| if (status == 0) msg = 0; |
| |
| #ifdef DEBUG |
| fprintf (stderr, "Server: Cmd(%d): %d\n", status, msg); |
| #endif |
| |
| switch (msg) |
| { |
| case 0: |
| fprintf (stderr, "Server: disconnecting\n"); |
| close (sock_cam); |
| FD_CLR (sock_cam, &active_fd_set); |
| connected = 0; |
| daq_end(); |
| break; |
| case 1: |
| read_socket (sock_cam, &data[8], 12); |
| daq_init (&data[8], idata[0]); |
| fprintf (stderr, "Server: Init finished\n"); |
| break; |
| case 2: |
| daq_clear (); |
| break; |
| case 3: |
| fprintf (stderr, "Server: Run Start\n"); |
| |
| read_socket (sock_cam, (char *) &recvdata[1], 8); |
| puts("Client disconnected"); |
| fflush(stdout); |
| } |
| else if(read_size == -1) |
| { |
| perror("recv failed"); |
| |
| daq_run ((const char *) recvdata, &data, &bufsize ); |
| idata = (int*)data; |
| #ifdef DEBUG |
| fprintf (stderr, "Server: Run end: %d\n", idata[0]); |
| #endif |
| } |
| if (daq_thread) { |
| pthread_cancel(daq_thread); |
| daq_thread = 0; |
| } |
| |
| write_socket (sock_cam, &msg, 1); |
| |
| //Free the socket pointer |
| free(socket_desc); |
| socket_desc = 0; |
| is_connected = 0; |
| |
| return 0; |
| } |
| |
| #ifdef DEBUG |
| fprintf (stderr, "Server: Data ready(%d): %d\n", status, msg); |
| #endif |
| |
| break; |
| case 4: |
| write_socket (sock_cam, &msg, 1); |
| write_socket (sock_cam, data, idata[0]); |
| |
| #ifdef DEBUG |
| fprintf (stderr, "Server: Data sent: %d, %d, %d\n", |
| idata[0], idata[1], idata[2]); |
| #endif |
| |
| break; |
| default: |
| fprintf (stderr, "Server: unknown command -> exiting...\n"); |
| exit (EXIT_FAILURE); |
| } |
| } |
| } |
| if (data !=NULL) free(data); |
| } |