/* RTMP - Socket Server $ID: $ */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <unistd.h> #include <fcntl.h> #include "rtmp.h" pthread_t listenerThread; pthread_mutex_t sConnectionsMutex; pthread_attr_t attr; myConnections_t *connections = 0x0; int sStartListener() { int optVal = 0x1; int listenerFD = 0x0; size_t stacksize; struct sockaddr_in myAddr; // my address information if ((listenerFD = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if (setsockopt(listenerFD, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } myAddr.sin_family = AF_INET; // host byte order myAddr.sin_port = htons(MYPORT); // short, network byte order myAddr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP memset(myAddr.sin_zero, '\0', sizeof myAddr.sin_zero); if (bind(listenerFD, (struct sockaddr *)&myAddr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } if (listen(listenerFD, BACKLOG) == -1) { perror("listen"); exit(1); } pthread_mutex_init(&sConnectionsMutex,NULL); pthread_attr_getstacksize(&attr,&stacksize); printf("SS: [0x%X]\n",stacksize); pthread_attr_setstacksize(&attr,sizeof(double)*N*N+MEGEXTRA); printf("SS: [0x%X]\n",stacksize); pthread_create(&listenerThread,&attr,sListenerThread,(void *)listenerFD); return(0x0); } ssize_t sReadSocket(int socketFD,void *buffer,size_t length) { ssize_t recLen = 0x0; ssize_t recLen2 = 0x0; fd_set readset; FD_ZERO(&readset); FD_SET(socketFD,&readset); while (select(socketFD + 1,&readset,0x0,0x0,0x0)) { if (FD_ISSET(socketFD,&readset)) break; } recLen = read(socketFD,buffer,length); if (recLen < length) { while (select(socketFD + 1,&readset,0x0,0x0,0x0)) { if (FD_ISSET(socketFD,&readset)) break; } recLen2 = read(socketFD,buffer + (recLen -1),(length - recLen)); recLen += recLen2; } return(recLen); } void *sListenerThread(void *lFD) { int listenerFD = (int)lFD; int newFD = 0x0; //New Socket; socklen_t sin_size; struct sockaddr_in remoteAddr; // connector's address information sin_size = sizeof(struct sockaddr_in); while (1) { printf("Waiting On Connection\n"); if ((newFD = accept(listenerFD, (struct sockaddr *)&remoteAddr, &sin_size)) == -1) { perror("accept"); } else { fcntl(newFD, F_SETFL, fcntl(newFD, F_GETFL, 0) | O_NONBLOCK); printf("server: got connection from %s\n",inet_ntoa(remoteAddr.sin_addr)); if (amfDoHandshake(newFD) == -1) { printf("Error: Bad Handshake\n"); close(newFD); } printf("A"); sAddConnection(newFD); } } } int sAddConnection(int socketFD) { myConnections_t *tmpConnection = 0x0; printf("Adding Socket"); pthread_mutex_lock(&sConnectionsMutex); if (connections == 0x0) { connections = (myConnections_t *)malloc(sizeof(myConnections_t)); connections->prev = 0x0; connections->next = 0x0; connections->socketFD = socketFD; } else { tmpConnection = (myConnections_t *)malloc(sizeof(myConnections_t)); tmpConnection->socketFD = socketFD; tmpConnection->prev = 0x0; tmpConnection->next = connections; connections->prev = tmpConnection; connections = tmpConnection; } printf("Socket Added"); pthread_mutex_unlock(&sConnectionsMutex); return(0x0); } int sGetConnections(fd_set *readset) { int retVal = 0; myConnections_t *tmpConnection = 0x0; FD_ZERO(readset); pthread_mutex_lock(&sConnectionsMutex); if (connections != 0x0) { for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { FD_SET(tmpConnection->socketFD,readset); } retVal = 1; } pthread_mutex_unlock(&sConnectionsMutex); return(retVal); }