#include "rec-sock-alsa.h" /* ***************************************************************** */ /* thread for dialog with client */ void * serve_partner(void * ptr); // global var: int running_servers = 0; int sockfd_server = 0; int conn1[nCHN]; int conn2[nCHN]; /* ***************************************************************** */ void * accept_conn(void * ptr) { pthread_t partner; int new_fd; struct sockaddr_in their_addr; int HasToBeVar = sizeof(their_addr); int sockfd = ((int *)ptr)[0]; fprintf(stderr,"Starting thread waiting for new connections\n"); bzero(&their_addr,sizeof(their_addr)); while ((run_server) && (sockfd_server > 0)) { if ((new_fd = accept(sockfd, &their_addr, &HasToBeVar)) == -1) { perror("accept"); continue; }; fprintf(stderr,"Starting additional server thread\n"); pthread_create (&partner, NULL, serve_partner, (void *)&new_fd); fprintf(stderr,"Additional server thread started\n"); }; LOCK; run_server = 0; // please stop serving // free some memory ... do other stuff ... UNLOCK; fprintf(stderr,"Waiting for servers to stop\n"); while (running_servers > 0) usleep(1000); close_socket(sockfd); return ptr; }; /* ***************************************************************** */ int open_socket(int port) /* liefert ein handle zurueck */ { struct sockaddr_in my_addr; int ch; int sockfd; pthread_t accepter; if ((port<1024) || (port>65519)) return 1; fprintf(stderr,"Initialising server sockets\n"); pthread_mutex_init(&mutex, NULL); for (ch=0; ch #define WIMP(n) LOCK; running_servers--; \ if (channel>=0) \ { \ conn1[channel] = (conn1[channel] == my_fd) ? 0 : conn1[channel]; \ conn2[channel] = (conn2[channel] == my_fd) ? 0 : conn2[channel]; \ }; \ UNLOCK; close(my_fd); \ fprintf(stderr,"End of server thread, fd=%d\n",my_fd); \ return ptr; // <- // could use n as some kind of error code... fprintf(stderr,"Server thread for another client started, fd=%d\n",my_fd); LOCK; running_servers++; UNLOCK; if (send(my_fd,"Hello!",strlen("Hello!")+1,0) == -1) { perror("send"); WIMP(1); }; if (recv(my_fd,combuf,sizeof(combuf),0) == -1) { perror("recv"); WIMP(1); }; combuf[sizeof(combuf)-1] = 0; if ((len>=0) && (len\n",combuf); if (strncmp(combuf,"GET",3)) { /* not GET, is it CLOSE ? */ if (!strncmp(combuf,"CLOSE",5)) { /* it is CLOSE */ LOCK; run_server = 0; // tell the others to stop too UNLOCK; fprintf(stderr,"CLOSE request detected, about to shut down\n"); WIMP(0); } else { /* unknown command */ fprintf(stderr,"Unknown command: %s\n",combuf); if (send(my_fd,"FAIL: Pardon?",strlen("FAIL: Pardon?")+1,0) == -1) { perror("send"); WIMP(1); }; WIMP(1); }; } else { /* command is GETn */ channel = atoi(combuf+3); if ((channel<0) || (channel >= nCHN)) { /* invalid channel selection */ fprintf(stderr,"Invalid channel in GET %d\n",channel); if (send(my_fd,"FAIL: Channel?",strlen("FAIL: Channel??")+1,0) == -1) { perror("send"); WIMP(1); }; WIMP(1); }; LOCK; if ((conn1[channel]) && (conn2[channel])) { fprintf(stderr,"Only two clients per channel allowed for now\n" "Channel %d busy (%d,%d)\n", channel,conn1[channel],conn2[channel]); if (send(my_fd,"FAIL: Busy",strlen("FAIL: Busy")+1,0) == -1) { perror("send"); UNLOCK; WIMP(1); }; UNLOCK; WIMP(1); }; if (conn1[channel]) conn2[channel]=my_fd; else conn1[channel]=my_fd; // and maybe alloc buffer and stuff UNLOCK; fprintf(stderr,"GET for channel %d accepted\n", channel); while (run_server) // send until client goes away or global shutdown { /* loop to satisfy GET */ if ((retval = send_buffer(my_fd, channel))) { fprintf(stderr,"Error %d while transmitting channel %d\n", retval,channel); WIMP(1); } else { /* fprintf(stderr,"."); */ }; // convert buffer (locked), send buffer, recv (discard) }; }; // end GET WIMP(0); };