#include #include "sockets/SocketW.h" #include #include #include #include #include "buffer.h" #include "user.h" #include "string.h" #define BUFLEN 1000000 int get_empty( user ** list, int amount ) { for (int i = 0; i < amount; i++ ){ if (!list[i]->is_connected){return i;} } return -1; } int main( int argc, char * argv[] ) { if (argc < 4) { std::cout << "usage: " << argv[0] << " buffers_count total_buffersize max_clients" << std::endl; return 1; } int buffers = atoi(argv[1]); int total_buffersize = atoi(argv[2]); int connections = atoi(argv[3]); int size_per_buffer = total_buffersize/buffers; std::cout << "Size per buffer: " << size_per_buffer << std::endl; buffer ** ringbuf = (buffer**) calloc (buffers,sizeof(buffer*)); for (int i = 0; i < buffers; i ++ ) { ringbuf[i] = new buffer; ringbuf[i]->data = (char*) malloc(size_per_buffer); } std::cout << "Successfully allocated " << total_buffersize << " bytes total buffer." << std::endl; user ** connectionList = (user**) calloc (connections,sizeof(user*)); for (int i = 0; i < connections; i++) { connectionList[i] = new user; } char header[13];//FLV header is always 13 bytes char metadata[BUFLEN]; int ret = 0; int frame_bodylength = 0; int current_buffer = 0; int open_connection = -1; int lastproper = 0;//last properly finished buffer number unsigned int loopcount = 0; SWUnixSocket listener; SWBaseSocket * incoming = 0; SWBaseSocket::SWBaseError BError; //read FLV header - 13 bytes ret = fread(&header,1,13,stdin); //TODO: check ret? listener.bind("/tmp/socketfile"); listener.listen(); listener.set_timeout(0,50000); //TODO: not while true, but while running - set running to false when kill signal is received! while(true) { loopcount ++; //invalidate the current buffer ringbuf[current_buffer]->size = 0; ringbuf[current_buffer]->number = -1; if (std::cin.peek() == 'F') { //new FLV file, read the file header again. ret = fread(&header,1,13,stdin); } else if( (int)std::cin.peek() == 12) { //metadata encountered, let's filter it ret = fread(&metadata,1,11,stdin); frame_bodylength = 4; frame_bodylength += metadata[3]; frame_bodylength += (metadata[2] << 8); frame_bodylength += (metadata[1] << 16); ret = fread(&metadata,1,frame_bodylength,stdin); } else { //read FLV frame header - 11 bytes ret = fread(ringbuf[current_buffer]->data,1,11,stdin); //TODO: Check ret? //if video frame? (id 9) check for incoming connections if (ringbuf[current_buffer]->data[0] == 9) { incoming = listener.accept(&BError); if (incoming){ open_connection = get_empty(connectionList,connections); if (open_connection != -1) { connectionList[open_connection]->connect(incoming); //send the FLV header std::cout << "Client " << open_connection << " connected." << std::endl; connectionList[open_connection]->MyBuffer = lastproper; connectionList[open_connection]->MyBuffer_num = ringbuf[lastproper]->number; //TODO: Do this more nicely? if (connectionList[open_connection]->Conn->send(&header[0],13,NULL) != 13){ connectionList[open_connection]->disconnect(); std::cout << "Client " << open_connection << " failed to receive the header!" << std::endl; } std::cout << "Client " << open_connection << " received header!" << std::endl; }else{ std::cout << "New client not connected: no more connections!" << std::endl; } } } //calculate body length of frame frame_bodylength = 4; frame_bodylength += ringbuf[current_buffer]->data[3]; frame_bodylength += (ringbuf[current_buffer]->data[2] << 8); frame_bodylength += (ringbuf[current_buffer]->data[1] << 16); //read the rest of the frame ret = fread(&ringbuf[current_buffer]->data[11],1,frame_bodylength,stdin); //TODO: Check ret? ringbuf[current_buffer]->size = frame_bodylength + 11; ringbuf[current_buffer]->number = loopcount; //send all connections what they need, if and when they need it for (int i = 0; i < connections; i++) {connectionList[i]->Send(ringbuf, buffers);} //keep track of buffers lastproper = current_buffer; current_buffer++; current_buffer %= buffers; } } // disconnect listener listener.disconnect(); //TODO: cleanup return 0; }