diff --git a/Client/Makefile b/Client/Makefile index e52f7a3e..532552af 100644 --- a/Client/Makefile +++ b/Client/Makefile @@ -1,4 +1,4 @@ -SRC = main.cpp sockets/sw_base.cpp sockets/sw_inet.cpp sockets/sw_unix.cpp +SRC = main.cpp ../sockets/sw_base.cpp ../sockets/sw_inet.cpp ../sockets/sw_unix.cpp OBJ = $(SRC:.cpp=.o) OUT = Client_PLS INCLUDES = diff --git a/Client/main.cpp b/Client/main.cpp index b10b2124..1917ae86 100644 --- a/Client/main.cpp +++ b/Client/main.cpp @@ -1,5 +1,5 @@ #include -#include "sockets/SocketW.h" +#include "../sockets/SocketW.h" #include #include #include @@ -9,7 +9,7 @@ int main() { SWUnixSocket mySocket; - mySocket.connect("/tmp/socketfile"); + mySocket.connect("../shared_socket"); char buffer[500000]; int msg; std::string input; diff --git a/Connector_RTMP/Makefile b/Connector_RTMP/Makefile index 3adaf18b..e07a6ee4 100644 --- a/Connector_RTMP/Makefile +++ b/Connector_RTMP/Makefile @@ -1,4 +1,4 @@ -SRC = main.cpp +SRC = main.cpp ../sockets/sw_base.cpp ../sockets/sw_inet.cpp ../sockets/sw_unix.cpp OBJ = $(SRC:.cpp=.o) OUT = Connector_RTMP INCLUDES = @@ -12,7 +12,7 @@ LIBS = default: $(OUT) .cpp.o: $(CC) $(INCLUDES) $(CCFLAGS) $(LIBS) -c $< -o $@ -$(OUT): $(OBJ) handshake.cpp chunkstream.cpp amf.cpp +$(OUT): $(OBJ) $(CC) $(LIBS) -o $(OUT) $(OBJ) clean: rm -rf $(OBJ) $(OUT) Makefile.bak *~ diff --git a/Connector_RTMP/chunkstream.cpp b/Connector_RTMP/chunkstream.cpp index 882febde..d983d290 100644 --- a/Connector_RTMP/chunkstream.cpp +++ b/Connector_RTMP/chunkstream.cpp @@ -119,6 +119,25 @@ void SendChunk(unsigned int cs_id, unsigned char msg_type_id, unsigned int msg_s free(ch.data); }//SendChunk +//sends a media chunk +void SendMedia(unsigned char msg_type_id, unsigned char * data, int len){ + if ((msg_type_id != 8) && (msg_type_id != 9)) return;//only parse audio and video + chunkpack ch; + timeval t; + gettimeofday(&t, 0); + ch.cs_id = msg_type_id; + ch.timestamp = t.tv_sec * 10 + t.tv_usec / 1000000; + ch.len = len; + ch.real_len = len; + ch.len_left = 0; + ch.msg_type_id = msg_type_id; + ch.msg_stream_id = 10; + ch.data = (unsigned char*)malloc(len); + memcpy(ch.data, data, len); + SendChunk(ch); + free(ch.data); +}//SendMedia + //sends a control message void SendCTL(unsigned char type, unsigned int data){ chunkpack ch; diff --git a/Connector_RTMP/main.cpp b/Connector_RTMP/main.cpp index 10423ca8..1941845c 100644 --- a/Connector_RTMP/main.cpp +++ b/Connector_RTMP/main.cpp @@ -10,12 +10,18 @@ #include #include +//for connection to server +#include "../sockets/SocketW.h" bool ready4data = false;//set to true when streaming starts - +bool inited = false; +#include "../util/flv.cpp" //FLV format parser #include "handshake.cpp" //handshaking #include "parsechunks.cpp" //chunkstream parsing int main(){ + SWUnixSocket ss; + FLV_Pack * FLV = 0; + int ssfd = 0; fd_set pollset; struct timeval timeout; //0 timeout - return immediately after select call @@ -26,14 +32,26 @@ int main(){ doHandshake(); while (!feof(stdin)){ select(1, &pollset, 0, 0, &timeout); - if (FD_ISSET(0, &pollset)){ - //only try to parse a new chunk when one is available :-) - std::cerr << "Parsing..." << std::endl; - parseChunk(); - } + //only parse input from stdin if available + if (FD_ISSET(0, &pollset)){parseChunk();} if (ready4data){ - //check for packets, send them if needed - std::cerr << "Sending crap..." << std::endl; + if (!inited){ + //we are ready, connect the socket! + ss.connect("../shared_socket"); + ssfd = ss.get_fd(0); + if (ssfd > 0){FD_SET(ssfd, &pollset);}else{return 1;} + FLV_Readheader(ssfd);//read the header, we don't want it + fprintf(stderr, "Header read\n"); + inited = true; + } + //only deal with FLV packets if we have any to receive + if (FD_ISSET(ssfd, &pollset)){ + fprintf(stderr, "Getting packet...\n"); + FLV_GetPacket(FLV, ssfd);//read a full packet + fprintf(stderr, "Sending a type %hhx packet...\n", (unsigned char)FLV->data[0]); + SendMedia((unsigned char)FLV->data[0], (unsigned char *)FLV->data+11, FLV->len-15); + fprintf(stderr, "Packet sent.\n"); + } } } return 0; diff --git a/Server/Makefile b/Server/Makefile index ad5f93e7..ace5d9e8 100644 --- a/Server/Makefile +++ b/Server/Makefile @@ -1,4 +1,4 @@ -SRC = main.cpp user.cpp sockets/sw_base.cpp sockets/sw_inet.cpp sockets/sw_unix.cpp +SRC = main.cpp ../sockets/sw_base.cpp ../sockets/sw_inet.cpp ../sockets/sw_unix.cpp OBJ = $(SRC:.cpp=.o) OUT = Server_PLS INCLUDES = diff --git a/Server/buffer.h b/Server/buffer.h index c3cf7627..c5d04955 100644 --- a/Server/buffer.h +++ b/Server/buffer.h @@ -2,6 +2,5 @@ struct buffer{ int number; - int size; - char * data; + FLV_Pack * FLV; };//buffer diff --git a/Server/main.cpp b/Server/main.cpp index e205e045..174565b8 100644 --- a/Server/main.cpp +++ b/Server/main.cpp @@ -1,14 +1,13 @@ #include -#include "sockets/SocketW.h" +#include "../sockets/SocketW.h" #include #include #include #include -#include "buffer.h" -#include "user.h" -#include "string.h" - -#define BUFLEN 1000000 +#include +#include +#include "../util/flv.cpp" //FLV format parser +#include "user.cpp" int get_empty( user ** list, int amount ) { for (int i = 0; i < amount; i++ ){ @@ -18,27 +17,16 @@ int get_empty( user ** list, int amount ) { } int main( int argc, char * argv[] ) { - if (argc < 4) { - std::cout << "usage: " << argv[0] << " buffers_count total_buffersize max_clients" << std::endl; + if (argc < 3) { + std::cout << "usage: " << argv[0] << " buffers_count 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; + int connections = atoi(argv[2]); 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; + for (int i = 0; i < buffers; ++i) ringbuf[i] = new buffer; + for (int i = 0; i < connections; ++i) connectionList[i] = new user; int current_buffer = 0; int open_connection = -1; int lastproper = 0;//last properly finished buffer number @@ -46,37 +34,23 @@ int main( int argc, char * argv[] ) { 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"); + unlink("../shared_socket"); + listener.bind("../shared_socket"); 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) { + + while(std::cin.good()) { 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); + FLV_Readheader(); } else { - //read FLV frame header - 11 bytes - ret = fread(ringbuf[current_buffer]->data,1,11,stdin); - //TODO: Check ret? + FLV_GetPacket(ringbuf[current_buffer]->FLV); //if video frame? (id 9) check for incoming connections - if (ringbuf[current_buffer]->data[0] == 9) { + if (ringbuf[current_buffer]->FLV->data[0] == 9) { incoming = listener.accept(&BError); if (incoming){ open_connection = get_empty(connectionList,connections); @@ -87,7 +61,7 @@ int main( int argc, char * argv[] ) { 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){ + if (connectionList[open_connection]->Conn->send(FLVHeader,13,0) != 13){ connectionList[open_connection]->disconnect(); std::cout << "Client " << open_connection << " failed to receive the header!" << std::endl; } @@ -97,15 +71,6 @@ int main( int argc, char * argv[] ) { } } } - //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);} @@ -117,7 +82,7 @@ int main( int argc, char * argv[] ) { } // disconnect listener + std::cout << "Reached EOF of input" << std::endl; listener.disconnect(); - //TODO: cleanup return 0; } diff --git a/Server/sockets/SocketW.h b/Server/sockets/SocketW.h deleted file mode 100644 index b7096c0c..00000000 --- a/Server/sockets/SocketW.h +++ /dev/null @@ -1,22 +0,0 @@ -// C++ Socket Wrapper -// -// Started 020316 -// -// License: LGPL v2.1+ (see the file LICENSE) -// (c)2002-2003 Anders Lindstr�m - -/*********************************************************************** - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - ***********************************************************************/ - -#ifndef SocketW_H -#define SocketW_H - -#include "sw_base.h" -#include "sw_unix.h" -#include "sw_inet.h" - -#endif //SocketW_H diff --git a/Server/sockets/sw_base.cpp b/Server/sockets/sw_base.cpp deleted file mode 100644 index 23ca1eb6..00000000 --- a/Server/sockets/sw_base.cpp +++ /dev/null @@ -1,764 +0,0 @@ -// C++ Socket Wrapper -// SocketW base class -// -// Started 020316 -// -// License: LGPL v2.1+ (see the file LICENSE) -// (c)2002-2003 Anders Lindstr�m - -/*********************************************************************** - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - ***********************************************************************/ - -#include "sw_base.h" -#include -#include -#include -#include -#include - -#ifndef __WIN32__ - #include - #include - #include - #include - #include - - #define INVALID_SOCKET -1 //avoid M$ braindamage -#else - //why use POSIX standards when we can make our own - //and frustrate people? (well known M$ policy) - - #ifndef EBADF - #define EBADF WSAEBADF - #endif - - #define ENOTSOCK WSAENOTSOCK - #define EOPNOTSUPP WSAEOPNOTSUPP - #define EADDRINUSE WSAEADDRINUSE - #define EWOULDBLOCK WSAEWOULDBLOCK - #define EMSGSIZE WSAEMSGSIZE - #define EINPROGRESS WSAEINPROGRESS - #define EALREADY WSAEALREADY - #define ECONNREFUSED WSAECONNREFUSED - #define ETIMEDOUT WSAETIMEDOUT - #define ENOTCONN WSAENOTCONN - - #ifndef EINTR - #define EINTR WSAEINTR - #endif -#endif - -#ifndef MSG_NOSIGNAL - #define MSG_NOSIGNAL 0 -#endif - -// Socklen hack -#if defined(__linux__) || defined(__FreeBSD__) // || defined(__bsdi__) || defined(__NetBSD__) too, perhaps? Bugreports, please! - #define sw_socklen_t socklen_t -#elif defined(__WIN32__) || defined(__osf__) - #define sw_socklen_t int -#else - #define sw_socklen_t unsigned int -#endif - - -using namespace std; - -#ifdef __WIN32__ -//Win32 braindamage -int close(int fd) -{ - return closesocket(fd); -} - -int fcntl(int fd, int cmd, long arg) -{ - unsigned long mode = arg; - - return WSAIoctl(fd, cmd, &mode, sizeof(unsigned long), NULL, 0, NULL, NULL, NULL); -} - -void WSA_exit(void) -{ - WSACleanup(); -} -#endif - - -//==================================================================== -//== Error handling mode -//==================================================================== -bool sw_DoThrow = false; -bool sw_Verbose = true; - -void sw_setThrowMode(bool throw_errors) -{ - sw_DoThrow = throw_errors; -} - -void sw_setVerboseMode(bool verbose) -{ - sw_Verbose = verbose; -} - -bool sw_getThrowMode(void) -{ - return sw_DoThrow; -} - -bool sw_getVerboseMode(void) -{ - return sw_Verbose; -} - - -//==================================================================== -//== Base error class -//==================================================================== -SWBaseSocket::SWBaseError::SWBaseError() -{ - be = ok; - error_string = ""; - failed_class = NULL; -} - -SWBaseSocket::SWBaseError::SWBaseError(base_error e) -{ - be = e; - error_string = ""; - failed_class = NULL; -} - -string SWBaseSocket::SWBaseError::get_error() -{ - return error_string; -} - -SWBaseSocket* SWBaseSocket::SWBaseError::get_failedClass(void) -{ - return failed_class; -} - -void SWBaseSocket::SWBaseError::set_errorString(string msg) -{ - error_string = msg; -} - -void SWBaseSocket::SWBaseError::set_failedClass(SWBaseSocket *pnt) -{ - failed_class = pnt; -} - -bool SWBaseSocket::SWBaseError::operator==(SWBaseError e) -{ - return be == e.be; -} - -bool SWBaseSocket::SWBaseError::operator!=(SWBaseError e) -{ - return be != e.be; -} - - -//==================================================================== -//== SWBaseSocket -//== Base class for sockets -//==================================================================== -SWBaseSocket::SWBaseSocket() -{ - //indicate nonopen - myfd = -1; - recv_close = false; - - //init values - error_string = ""; - block_mode = blocking; - fsend_ready = true; - frecv_ready = true; - tsec = 0; - tusec = 0; - - #ifdef __WIN32__ - //kick winsock awake - static bool firstuse = true; - if( firstuse == true ){ - WSAData wsaData; - int nCode; - if( (nCode = WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0 ){ - handle_errno(NULL, "SWBaseSocket - WSAStartup() failed: "); - exit(-1); // Should never happend - } - - //cleanup at exit - atexit(WSA_exit); - firstuse = false; - } - #endif /* __WIN32__ */ -} - -SWBaseSocket::~SWBaseSocket() -{ - if(myfd > 0) - close(myfd); -} - -bool SWBaseSocket::listen(int qLimit, SWBaseError *error) -{ - get_socket(); - - //Avoid "Address already in use" thingie - char yes=1; - setsockopt(myfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); - - if(::listen(myfd, qLimit) == -1){ - handle_errno(error, "SWBaseSocket::listen() error: "); - return false; - } - - no_error(error); - return true; -} - -SWBaseSocket* SWBaseSocket::accept(SWBaseError *error) -{ - int remotefd = -1; - sockaddr remoteAdr; - - if( !waitRead(error) ) - return NULL; - - sw_socklen_t ssize = sizeof(sockaddr); - - if((remotefd = ::accept(myfd, &remoteAdr, &ssize)) == int(INVALID_SOCKET)){ - handle_errno(error, "SWBaseSocket::accept() error: "); - return NULL; - } - - //nonblocking? - if( block_mode == nonblocking ) - fcntl(remotefd, F_SETFL, O_NONBLOCK); - - /* Create new class*/ - SWBaseSocket* remoteClass = create(remotefd, error); - if( remoteClass == NULL ) - return NULL; - - no_error(error); - return remoteClass; -} - -bool SWBaseSocket::disconnect(SWBaseError *error) -{ - int n = 0; - char buf[256]; - - if(myfd < 0){ - set_error(error, notConnected, "SWBaseSocket::disconnect() - No connection"); - return false; - } - - //close WR (this signals the peer) - if( shutdown(myfd, 1) != 0 ){ - handle_errno(error, "SWBaseSocket::disconnect() error: "); - return false; - } - - - SWBaseError err; - - //wait for close signal from peer - if( recv_close == false ){ - while(true){ - if( !waitRead(error) ) - return false; - - n = recv(buf, 256, &err); - - if( n <= 0 ) - break; - if(block_mode == noWait){ - //we don't want to block - set_error(error, notReady, "SWBaseSocket::disconnect() - Need more time, call again"); - return false; - } - } - } - - if( n != 0 ){ - set_error(error, err, error_string); - return false; //error - } - - //reset state - reset(); - - close(myfd); - myfd = -1; - - no_error(error); - return true; -} - -bool SWBaseSocket::close_fd() -{ - if( myfd > 0 ){ - close(myfd); - myfd = -1; - - //reset state - reset(); - - return true; - } - return false; -} - -int SWBaseSocket::send(const char *buf, int bytes, SWBaseError *error) -{ - int ret; - - if(myfd < 0){ - set_error(error, notConnected, "SWBaseSocket::send() - No connection"); - return -1; - } - - if( !waitWrite(error) ) - return -1; - - ret = ::send(myfd, buf, bytes, MSG_NOSIGNAL); - - if( ret < 0 ) - handle_errno(error, "SWBaseSocket::send() error: "); - else - no_error(error); - - return ret; -} - -int SWBaseSocket::fsend(const char *buf, int bytes, SWBaseError *error) -{ - int n; - int bytessent; - - if(fsend_ready){ - //First call - fsend_bytesleft = bytes; - fsend_total = fsend_bytesleft; //global var needed for resume - bytessent = 0; - fsend_ready = false; //point of no return - } - else{ - //resume - bytessent = fsend_total - fsend_bytesleft; - } - - //send package - while( fsend_bytesleft > 0 ){ - n = send( buf + bytessent , fsend_bytesleft, error ); - - //return on error, wouldblock or nowait - if( n < 0 ) - return ( (bytessent > 0 )? -bytessent : -1 ); - - bytessent += n; - fsend_bytesleft -= n; - - if ( block_mode == noWait && fsend_bytesleft > 0 ){ - set_error(error, notReady, "SWBaseSocket::fsend() - Need more time, call again"); - return -bytessent; - } - } - - fsend_ready = true; - - no_error(error); - return fsend_total; -} - -int SWBaseSocket::sendmsg(const string msg, SWBaseError *error) -{ - return send(msg.c_str(), msg.size(), error); -} - -int SWBaseSocket::fsendmsg(const string msg, SWBaseError *error) -{ - return fsend(msg.c_str(), msg.size(), error); -} - -int SWBaseSocket::recv(char *buf, int bytes, SWBaseError *error) -{ - int ret; - - if(myfd < 0){ - set_error(error, notConnected, "SWBaseSocket::recv() - No connection"); - return -1; - } - - if( !waitRead(error) ) - return -1; - - ret = ::recv(myfd, buf, bytes, MSG_NOSIGNAL); - - if( ret < 0 ) - handle_errno(error, "SWBaseSocket::recv() error: "); - else if( ret == 0 ){ - recv_close = true; //we recived a close signal from peer - set_error(error, terminated, "SWBaseSocket::recv() - Connection terminated by peer"); - }else - no_error(error); - - return ret; -} - -int SWBaseSocket::frecv(char *buf, int bytes, SWBaseError *error) -{ - int n; - int bytesrecv; - - if(frecv_ready){ - //First call - frecv_bytesleft = bytes; - frecv_total = frecv_bytesleft; //global var needed for resume - bytesrecv = 0; - frecv_ready = false; //point of no return - } - else{ - //resume - bytesrecv = frecv_total - frecv_bytesleft; - } - - - //recv package - while( frecv_bytesleft > 0 ){ - n = recv( buf + bytesrecv , frecv_bytesleft, error ); - - //return on error, wouldblock, nowait or timeout - if( n < 0 ) - return ( (bytesrecv > 0 )? -bytesrecv : -1 ); - if( n == 0 ) - return 0; // terminated - - bytesrecv += n; - frecv_bytesleft -= n; - - if ( block_mode == noWait && frecv_bytesleft > 0 ){ - set_error(error, notReady, "SWBaseSocket::frecv() - Need more time, call again"); - return -bytesrecv; - } - } - - frecv_ready = true; - - no_error(error); - return frecv_total; -} - -string SWBaseSocket::recvmsg(int bytes, SWBaseError *error) -{ - char *buf = new char[bytes+1]; - - SWBaseError err; - string msg = ""; - int ret = recv(buf, bytes, &err); - - if( ret > 0 ){ - buf[ret]='\0'; // Make sure the string is null terminated - msg = buf; - no_error(error); - } - delete[] buf; - - if( ret < 1 ) - set_error(error, err, err.get_error()); - - return msg; -} - -int SWBaseSocket::get_fd(SWBaseError *error) -{ - if( myfd > 0 ){ - no_error(error); - return myfd; - } - - set_error(error, notConnected, "SWBaseSocket::get_fd() - No descriptor"); - return -1; -} - -bool SWBaseSocket::get_host(sockaddr *host, SWBaseError *error) -{ - if( host == NULL){ - set_error(error, fatal, "SWBaseSocket::get_host() - Got NULL pointer"); - return false; - } - - if(myfd < 0){ - set_error(error, notConnected, "SWBaseSocket::get_host() - No socket"); - return false; - } - - sw_socklen_t tmp = sizeof(sockaddr); - if( getsockname(myfd, host, &tmp) != 0 ){ - handle_errno(error, "SWBaseSocket::get_host() error: "); - return false; - } - - no_error(error); - return true; -} - -bool SWBaseSocket::get_peer(sockaddr *peer, SWBaseError *error) -{ - if( peer == NULL){ - set_error(error, fatal, "SWBaseSocket::get_peer() - Got NULL pointer"); - return false; - } - - if(myfd > 0){ - sw_socklen_t tmp = sizeof(sockaddr); - if( getpeername(myfd, peer, &tmp) != 0 ){ - handle_errno(error, "SWBaseSocket::get_peer() error: "); - return false; - } - }else{ - set_error(error, notConnected, "SWBaseSocket::get_peer() - No connection"); - return false; - } - - no_error(error); - return true; -} - -void SWBaseSocket::reset() -{ - // Reset flags - recv_close = false; - - fsend_ready = true; - frecv_ready = true; -} - -bool SWBaseSocket::waitIO(io_type &type, SWBaseError *error) -{ - if( block_mode != blocking ){ - no_error(error); - return true; - } - - // We prefere to wait with select() even if no timeout is set - // as select() behaves more predictable - - timeval t; - timeval *to = NULL; // Indicate "wait for ever" - t.tv_sec = tsec; - t.tv_usec = tusec; - - if( tsec > 0 || tusec > 0 ) - to = &t; - - fd_set readfds, writefds, exceptfds; - - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_ZERO(&exceptfds); - FD_SET(myfd, &readfds); - FD_SET(myfd, &writefds); - FD_SET(myfd, &exceptfds); - - int ret = 0; - - switch (type){ - case read: - ret = select(myfd+1, &readfds, NULL, NULL, to); - break; - case write: - ret = select(myfd+1, NULL, &writefds, NULL, to); - break; - case except: - ret = select(myfd+1, NULL, NULL, &exceptfds, to); - break; - case rw: - ret = select(myfd+1, &readfds, &writefds, NULL, to); - break; - case all: - ret = select(myfd+1, &readfds, &writefds, &exceptfds, to); - break; - } - - if( ret < 0 ){ - handle_errno(error, "SWBaseSocket::waitIO() error: "); - return false; - } - if( ret == 0 ){ - set_error(error, timeout, "SWBaseSocket::waitIO() timeout"); - return false; - } - - if( FD_ISSET(myfd, &readfds) ){ - no_error(error); - type = read; - return true; - } - if( FD_ISSET(myfd, &writefds) ){ - no_error(error); - type = write; - return true; - } - if( FD_ISSET(myfd, &exceptfds) ){ - no_error(error); - type = except; - return true; - } - - set_error(error, fatal, "SWBaseSocket::waitIO() failed on select()"); - return false; -} - -bool SWBaseSocket::waitRead(SWBaseError *error) -{ - io_type tmp = read; - return waitIO(tmp, error); -} - -bool SWBaseSocket::waitWrite(SWBaseError *error) -{ - io_type tmp = write; - return waitIO(tmp, error); -} - -void SWBaseSocket::print_error() -{ - if( error_string.size() > 0 ) - fprintf(stderr, "%s!\n", error_string.c_str()); -} - -void SWBaseSocket::handle_errno(SWBaseError *error, string msg) -{ - #ifndef __WIN32__ - msg += strerror(errno); - #else - //stupid stupid stupid stupid M$ - switch (WSAGetLastError()){ - case 0: msg += "No error"; break; - case WSAEINTR: msg += "Interrupted system call"; break; - case WSAEBADF: msg += "Bad file number"; break; - case WSAEACCES: msg += "Permission denied"; break; - case WSAEFAULT: msg += "Bad address"; break; - case WSAEINVAL: msg += "Invalid argument"; break; - case WSAEMFILE: msg += "Too many open sockets"; break; - case WSAEWOULDBLOCK: msg += "Operation would block"; break; - case WSAEINPROGRESS: msg += "Operation now in progress"; break; - case WSAEALREADY: msg += "Operation already in progress"; break; - case WSAENOTSOCK: msg += "Socket operation on non-socket"; break; - case WSAEDESTADDRREQ: msg += "Destination address required"; break; - case WSAEMSGSIZE: msg += "Message too long"; break; - case WSAEPROTOTYPE: msg += "Protocol wrong type for socket"; break; - case WSAENOPROTOOPT: msg += "Bad protocol option"; break; - case WSAEPROTONOSUPPORT: msg += "Protocol not supported"; break; - case WSAESOCKTNOSUPPORT: msg += "Socket type not supported"; break; - case WSAEOPNOTSUPP: msg += "Operation not supported on socket"; break; - case WSAEPFNOSUPPORT: msg += "Protocol family not supported"; break; - case WSAEAFNOSUPPORT: msg += "Address family not supported"; break; - case WSAEADDRINUSE: msg += "Address already in use"; break; - case WSAEADDRNOTAVAIL: msg += "Can't assign requested address"; break; - case WSAENETDOWN: msg += "Network is down"; break; - case WSAENETUNREACH: msg += "Network is unreachable"; break; - case WSAENETRESET: msg += "Net connection reset"; break; - case WSAECONNABORTED: msg += "Software caused connection abort"; break; - case WSAECONNRESET: msg += "Connection reset by peer"; break; - case WSAENOBUFS: msg += "No buffer space available"; break; - case WSAEISCONN: msg += "Socket is already connected"; break; - case WSAENOTCONN: msg += "Socket is not connected"; break; - case WSAESHUTDOWN: msg += "Can't send after socket shutdown"; break; - case WSAETOOMANYREFS: msg += "Too many references"; break; - case WSAETIMEDOUT: msg += "Connection timed out"; break; - case WSAECONNREFUSED: msg += "Connection refused"; break; - case WSAELOOP: msg += "Too many levels of symbolic links"; break; - case WSAENAMETOOLONG: msg += "File name too long"; break; - case WSAEHOSTDOWN: msg += "Host is down"; break; - case WSAEHOSTUNREACH: msg += "No route to host"; break; - case WSAENOTEMPTY: msg += "Directory not empty"; break; - case WSAEPROCLIM: msg += "Too many processes"; break; - case WSAEUSERS: msg += "Too many users"; break; - case WSAEDQUOT: msg += "Disc quota exceeded"; break; - case WSAESTALE: msg += "Stale NFS file handle"; break; - case WSAEREMOTE: msg += "Too many levels of remote in path"; break; - case WSASYSNOTREADY: msg += "Network system is unavailable"; break; - case WSAVERNOTSUPPORTED: msg += "Winsock version out of range"; break; - case WSANOTINITIALISED: msg += "WSAStartup not yet called"; break; - case WSAEDISCON: msg += "Graceful shutdown in progress"; break; - case WSAHOST_NOT_FOUND: msg += "Host not found"; break; - case WSANO_DATA: msg += "No host data of that type was found"; break; - default: msg += "Unknown Winsock error: " + WSAGetLastError(); break; - } - #endif - - int errorno; - - //Win32 braindamage - #ifdef __WIN32__ - errorno = WSAGetLastError(); - #else - errorno = errno; - #endif - - SWBaseError e; - - if( errorno == EADDRINUSE ) - e = portInUse; - else if( errorno == EAGAIN || errorno == EWOULDBLOCK ) - e = notReady; - else if( errorno == EMSGSIZE ) - e = msgTooLong; - else if( errorno == EINPROGRESS || errorno == EALREADY ) - e = notReady; - else if( errorno == ECONNREFUSED || errorno == ETIMEDOUT ) - e = noResponse; - else if( errorno == ENOTCONN || errorno == EBADF || errorno == ENOTSOCK ) - e = notConnected; - else if( errorno == EPIPE ){ - e = terminated; - recv_close = true; - }else if( errorno == EINTR ) - e = interrupted; - else - e = fatal; //default - - set_error(error, e, msg); -} - -void SWBaseSocket::no_error(SWBaseError *error) -{ - if(error != NULL){ - *error = ok; - error->error_string = ""; - error->failed_class = NULL; - } -} - -void SWBaseSocket::set_error(SWBaseError *error, SWBaseError name, string msg) -{ - error_string = msg; - - if(error != NULL){ - *error = name; - error->error_string = msg; - error->failed_class = this; - }else{ - if( sw_Verbose ) - print_error(); - - if( sw_DoThrow ){ - SWBaseError e; - e = name; - e.error_string = msg; - e.failed_class = this; - throw e; - } - } -} - diff --git a/Server/sockets/sw_base.h b/Server/sockets/sw_base.h deleted file mode 100644 index a6a191f1..00000000 --- a/Server/sockets/sw_base.h +++ /dev/null @@ -1,205 +0,0 @@ -// C++ Socket Wrapper -// SocketW base socket header -// -// Started 020316 -// -// License: LGPL v2.1+ (see the file LICENSE) -// (c)2002-2003 Anders Lindström - -/*********************************************************************** - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - ***********************************************************************/ - -#ifndef sw_base_H -#define sw_base_H - -#include "sw_internal.h" - -#include -#include - -// Set error handling mode -// throw_errors == true : Throws the error class on unhandled errors -// throw_errors == false : Exit on unhandled errors -// verbose == true : Prints the error message to stderr on unhandled errors -// -// Default is throw_errors == false and verbose == true -void sw_setThrowMode(bool throw_errors); -void sw_setVerboseMode(bool verbose); -bool sw_getThrowMode(void); -bool sw_getVerboseMode(void); - - -// Abstract base class for streaming sockets -class DECLSPEC SWBaseSocket -{ -public: - SWBaseSocket(); - virtual ~SWBaseSocket(); - - // Error types - // ok - operation succesful - // fatal - unspecified error - // notReady - you should call the function again - // indicates that the function would block (if nowait/nonblocking) - // portInUse - this port is used by another socket ( on listen() ) - // notConnected - socket not connected (or valid) - // msgTooLong - the message size it too big for send() - // terminated - connection terminated (by peer) - // noResponse - can't connect() to peer - // timeout - a read/write operation timed out (only if a timeout value is set and if in blocking mode) - // interrupted - operation was interrupted by a nonblocked signal - enum base_error{ok, fatal, notReady, portInUse, notConnected, msgTooLong, terminated, noResponse, timeout, interrupted}; - - class DECLSPEC SWBaseError - { - public: - SWBaseError(); - SWBaseError(base_error e); - - virtual ~SWBaseError(){;} - - virtual std::string get_error(); - virtual SWBaseSocket* get_failedClass(void); - - virtual bool operator==(SWBaseError e); - virtual bool operator!=(SWBaseError e); - - virtual void set_errorString(std::string msg); - virtual void set_failedClass(SWBaseSocket *pnt); - protected: - friend class SWBaseSocket; - - // The base error type - base_error be; - - // Human readable error string - std::string error_string; - - // A pointer to the class causing the error - SWBaseSocket *failed_class; - }; - - - // Note: If no SWBaseError class is provided with a method call (==NULL), - // SocketW will print the error to stderr and exit or throw on errors. - - // Note: All bool functions returns true on success. - - // Block mode - // blocking - everythings blocks until completly done - // noWait - operations block but only once - // useful with blocking w. select() - // nonblocking - don't block (you should use select()) - enum block_type{blocking, noWait, nonblocking}; - - - // Connection methods - // qLimit - the maximum length the queue of pending connections. - // Accept returns a new socket class connected with peer (should be - // freed with delete) or NULL on failure. You can cast the class to - // the correct type if you need to ( eg. (SWInetSocket *)mysocket ). - virtual bool listen(int qLimit = 5, SWBaseError *error = NULL); - virtual SWBaseSocket* accept(SWBaseError *error = NULL); - // bind() and connect() are implemented in child classes - - // do the disconnect ritual (signal peer, wait for close singal and close socket) - virtual bool disconnect(SWBaseError *error = NULL); - - // force close socket - virtual bool close_fd(); //use with care, disconnect() is cleaner - - // Direct I/O (raw) - // Can send/recv less bytes than specified! - // Returns the actual amount of bytes sent/recv on sucess - // and an negative integer on failure. - virtual int send(const char *buf, int bytes, SWBaseError *error = NULL); - virtual int sendmsg(const std::string msg, SWBaseError *error = NULL); - virtual int recv(char *buf, int bytes, SWBaseError *error = NULL); - virtual std::string recvmsg(int bytes = 256, SWBaseError *error = NULL); - - // Forced I/O - // Force system to send/recv the specified amount of bytes. - // On nowait/nonblocking: might return with notReady and then you - // MUST call the same method again (eg. wait with select() to know when) - // with the same parameters until the operation is finished. - // Returns 'bytes' when finished, negative integer on failure and - // 'notReady'. In the 'notReady' case, -(return value) is the amount of - // bytes sent/recv so far. - virtual int fsend(const char *buf, int bytes, SWBaseError *error = NULL); - virtual int fsendmsg(const std::string msg, SWBaseError *error = NULL); - virtual int frecv(char *buf, int bytes, SWBaseError *error = NULL); - - // Tools - // get_fd() - get socket descriptor, can be used with select() - // returns -1 on failure. - // get_host/peer fills the provided structures with info about the - // host/peer (see man unix & ip). - // SWInetSocket has some more tools for TCP/IP sockets. - virtual int get_fd(SWBaseError *error); - virtual bool get_host(sockaddr *host, SWBaseError *error = NULL); - virtual bool get_peer(sockaddr *peer, SWBaseError *error = NULL); - - // Set recv timeout (only in blocking mode). - // set_timeout(0,0) means wait forever (default). - // This affects the functions recv(), send(), accept() and disconnect() - // and others that use those, i.e. all frecvmsg(). - void set_timeout(Uint32 sec, Uint32 usec){ tsec = sec, tusec = usec; } - - // Error handling - virtual void print_error(); //prints the last error if any to stderr - virtual std::string get_error(){return error_string;} //returns a human readable error string - -protected: - // get a new socket if myfd < 0 - virtual void get_socket()=0; - - // create a new class for accept() using socketdescriptor - virtual SWBaseSocket* create(int socketdescriptor, SWBaseError *error)=0; - - // reset state - virtual void reset(); - - // wait for I/O (with timeout) - enum io_type{read, write, except, rw, all}; - virtual bool waitIO(io_type &type, SWBaseError *error); - bool waitRead(SWBaseError *error); - bool waitWrite(SWBaseError *error); - - // internal error handling - virtual void handle_errno(SWBaseError *error, std::string msg); - virtual void no_error(SWBaseError *error); - virtual void set_error(SWBaseError *error, SWBaseError name, std::string msg); - - // our socket descriptor - int myfd; - - // last error - std::string error_string; - - // data for fsend - bool fsend_ready; - int fsend_total; - int fsend_bytesleft; - - // data for frecv - bool frecv_ready; - int frecv_total; - int frecv_bytesleft; - - // have we recived a shutdown signal? - bool recv_close; - - //blocking mode (set by child classes) - block_type block_mode; - - //timeout for waitIO() - int tsec; - int tusec; -}; - - -#endif /* sw_base_H */ diff --git a/Server/sockets/sw_inet.cpp b/Server/sockets/sw_inet.cpp deleted file mode 100644 index c056722e..00000000 --- a/Server/sockets/sw_inet.cpp +++ /dev/null @@ -1,249 +0,0 @@ -// C++ Socket Wrapper -// SocketW Inet socket -// -// Started 020316 -// -// License: LGPL v2.1+ (see the file LICENSE) -// (c)2002-2003 Anders Lindström - -/*********************************************************************** - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - ***********************************************************************/ - -#include "sw_inet.h" - -#ifndef __WIN32__ - #include - #include - #include - #include - #include -#else - #define F_SETFL FIONBIO - #define O_NONBLOCK 1 - - //Defined in sw_base.cxx - extern int close(int fd); - extern int fcntl(int fd, int cmd, long arg); -#endif - -using namespace std; - -//==================================================================== -//== SWInetSocket -//== Inet (TCP/IP) streaming sockets -//==================================================================== -SWInetSocket::SWInetSocket(block_type block) -{ - block_mode = block; -} - -SWInetSocket::~SWInetSocket() -{ - -} - -void SWInetSocket::get_socket() -{ - if( myfd < 0 ){ - myfd = socket(PF_INET, SOCK_STREAM, 0); - - if( block_mode == nonblocking ) - fcntl(myfd, F_SETFL, O_NONBLOCK); - - //reset state - reset(); - } -} - -SWBaseSocket* SWInetSocket::create(int socketdescriptor, SWBaseError *error) -{ - SWInetSocket* remoteClass; - - /* Create new class*/ - remoteClass = new SWInetSocket(block_mode); - remoteClass->myfd = socketdescriptor; - - no_error(error); - return remoteClass; -} - -bool SWInetSocket::bind(int port, SWBaseError *error) -{ - return bind(port, "", error); -} - -bool SWInetSocket::bind(int port, string host, SWBaseError *error) -{ - hostent *h; - in_addr inp; - - if( host.size() > 0 ){ - // Bind to a specific address - - if( (h = gethostbyname(host.c_str())) == NULL ){ - set_error(error, fatal, "SWInetSocket::bind() - Can't get host by name"); - return false; - } - - inp = *((in_addr *)h->h_addr); - }else{ - // Bind to any - inp.s_addr = INADDR_ANY; - } - - - get_socket(); - - sockaddr_in myAdr; - - memset(&myAdr, 0, sizeof(myAdr)); - myAdr.sin_family = AF_INET; - myAdr.sin_port = htons(port); - myAdr.sin_addr.s_addr = inp.s_addr; - - if(::bind(myfd, (sockaddr *)&myAdr, sizeof(myAdr)) == -1){ - handle_errno(error, "SWInetSocket::bind() error: "); - return false; - } - - no_error(error); - return true; -} - -bool SWInetSocket::connect(int port, string hostname, SWBaseError *error) -{ - get_socket(); - - hostent *host; - - if( (host = gethostbyname(hostname.c_str())) == NULL ){ - set_error(error, fatal, "SWInetSocket::connect() - Can't get host by name"); - return false; - } - - sockaddr_in remoteAdr; - - memset(&remoteAdr, 0, sizeof(remoteAdr)); - remoteAdr.sin_family = AF_INET; - remoteAdr.sin_port = htons(port); - remoteAdr.sin_addr = *((in_addr *)host->h_addr); - - if(::connect(myfd, (sockaddr *)&remoteAdr, sizeof(remoteAdr)) == -1){ - handle_errno(error, "SWInetSocket::connect() error: "); - return false; - } - - no_error(error); - return true; -} - - -string SWInetSocket::get_peerAddr(SWBaseError *error) -{ - sockaddr_in adr; - - if( !get_peer((sockaddr *)&adr, error) ) - return ""; - - char *pnt; - - if( (pnt = inet_ntoa(adr.sin_addr)) == NULL ){ - set_error(error, fatal, "SWInetSocket::get_peerName() - Can't get peer address"); - return ""; - } - string name(pnt); - - no_error(error); - return name; -} - -int SWInetSocket::get_peerPort(SWBaseError *error) -{ - sockaddr_in adr; - - if( !get_peer((sockaddr *)&adr, error) ) - return -1; - - no_error(error); - - return ntohs(adr.sin_port); -} - -string SWInetSocket::get_peerName(SWBaseError *error) -{ - string name = get_peerAddr(error); - if(name.size() < 1) - return ""; - - - hostent *h; - - if( (h = gethostbyname(name.c_str())) == NULL ){ - set_error(error, fatal, "SWInetSocket::get_peerName() - Can't get peer by address"); - return ""; - } - string host_name(h->h_name); - - no_error(error); - return host_name; -} - -string SWInetSocket::get_hostAddr(SWBaseError *error) -{ - //We need to get the real address, so we must - //first get this computers host name and then - //translate that into an address! - - string name = get_hostName(error); - if( name.size() < 1 ) - return ""; - - hostent *host; - - if( (host = gethostbyname(name.c_str())) == NULL ){ - set_error(error, fatal, "SWInetSocket::get_hostAddr() - Can't get host by name"); - return ""; - } - - char *pnt; - - if( (pnt = inet_ntoa(*((in_addr *)host->h_addr))) == NULL){ - set_error(error, fatal, "SWInetSocket::get_hostAddr() - Can't get host address"); - return ""; - } - - string adr(pnt); - - return adr; -} - -int SWInetSocket::get_hostPort(SWBaseError *error) -{ - sockaddr_in adr; - - if( !get_host((sockaddr *)&adr, error) ) - return -1; - - no_error(error); - - return ntohs(adr.sin_port); -} - -string SWInetSocket::get_hostName(SWBaseError *error) -{ - char buf[256]; - - if( gethostname(buf, 256) != 0 ){ - handle_errno(error, "SWInetSocket::gethostname() error: "); - return ""; - } - - string msg(buf); - - no_error(error); - return msg; -} diff --git a/Server/sockets/sw_inet.h b/Server/sockets/sw_inet.h deleted file mode 100644 index 26050845..00000000 --- a/Server/sockets/sw_inet.h +++ /dev/null @@ -1,48 +0,0 @@ -// C++ Socket Wrapper -// SocketW Inet socket header -// -// Started 020316 -// -// License: LGPL v2.1+ (see the file LICENSE) -// (c)2002-2003 Anders Lindström - -/*********************************************************************** - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - ***********************************************************************/ - -#ifndef sw_inet_H -#define sw_inet_H - -#include "sw_internal.h" -#include "sw_base.h" -#include - -// Simple streaming TCP/IP class -class DECLSPEC SWInetSocket : public SWBaseSocket -{ -public: - SWInetSocket(block_type block=blocking); - virtual ~SWInetSocket(); - - virtual bool bind(int port, SWBaseError *error = NULL); //use port=0 to get any free port - virtual bool bind(int port, std::string host, SWBaseError *error = NULL); //you can also specify the host interface to use - virtual bool connect(int port, std::string hostname, SWBaseError *error = NULL); - - // Tools - // Gets IP addr, name or port. - virtual std::string get_peerAddr(SWBaseError *error = NULL); - virtual int get_peerPort(SWBaseError *error = NULL); - virtual std::string get_peerName(SWBaseError *error = NULL); - virtual std::string get_hostAddr(SWBaseError *error = NULL); - virtual int get_hostPort(SWBaseError *error = NULL); - virtual std::string get_hostName(SWBaseError *error = NULL); - -protected: - virtual void get_socket(); - virtual SWBaseSocket* create(int socketdescriptor, SWBaseError *error); -}; - -#endif /* sw_inet_H */ diff --git a/Server/sockets/sw_internal.h b/Server/sockets/sw_internal.h deleted file mode 100644 index 94313bcd..00000000 --- a/Server/sockets/sw_internal.h +++ /dev/null @@ -1,75 +0,0 @@ -// C++ Socket Wrapper -// SocketW internal header -// -// Started 030823 -// -// License: LGPL v2.1+ (see the file LICENSE) -// (c)2002-2003 Anders Lindstr�m - -/*********************************************************************** - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - ***********************************************************************/ - -#ifndef sw_internal_H -#define sw_internal_H - -// This header is included in all *.h files - -#ifndef __WIN32__ - #include - #include - #include - #include -#else - #include - - #define F_SETFL FIONBIO - #define O_NONBLOCK 1 -#endif - -#ifndef _SDL_H - -// Define general types -typedef unsigned char Uint8; -typedef signed char Sint8; -typedef unsigned short Uint16; -typedef signed short Sint16; -typedef unsigned int Uint32; -typedef signed int Sint32; - -// It's VERY important that these types really have the right sizes! -// This black magic is from SDL -#define COMPILE_TIME_ASSERT(name, x) \ - typedef int _dummy_ ## name[(x) * 2 - 1] -COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); -COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1); -COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2); -COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2); -COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4); -COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4); -#undef COMPILE_TIME_ASSERT - -#endif /* _SDL_H */ - -// Some compilers use a special export keyword -#ifndef DECLSPEC - #ifdef __BEOS__ - #if defined(__GNUC__) - #define DECLSPEC __declspec(dllexport) - #else - #define DECLSPEC __declspec(export) - #endif - #else - #ifdef WIN32 - #define DECLSPEC __declspec(dllexport) - #else - #define DECLSPEC - #endif - #endif -#endif - - -#endif /* sw_internal_H */ diff --git a/Server/sockets/sw_unix.cpp b/Server/sockets/sw_unix.cpp deleted file mode 100644 index 07e2dd10..00000000 --- a/Server/sockets/sw_unix.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// C++ Socket Wrapper -// SocketW Unix socket -// -// Started 020316 -// -// License: LGPL v2.1+ (see the file LICENSE) -// (c)2002-2003 Anders Lindström - -/*********************************************************************** - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - ***********************************************************************/ - -#include "sw_unix.h" -#include - -using namespace std; - -//==================================================================== -//== SWUnixSocket -//== Unix streaming sockets -//==================================================================== -#ifndef __WIN32__ - -SWUnixSocket::SWUnixSocket(block_type block) -{ - block_mode = block; -} - -SWUnixSocket::~SWUnixSocket() -{ - //nothing here -} - -void SWUnixSocket::get_socket() -{ - if( myfd < 0 ){ - myfd = socket(PF_UNIX, SOCK_STREAM, 0); - - if( block_mode == nonblocking ) - fcntl(myfd, F_SETFL, O_NONBLOCK); - - //reset state - reset(); - } -} - - -SWBaseSocket* SWUnixSocket::create(int socketdescriptor, SWBaseError *error) -{ - SWUnixSocket* remoteClass; - - /* Create new class*/ - remoteClass = new SWUnixSocket(block_mode); - remoteClass->myfd = socketdescriptor; - - no_error(error); - return remoteClass; -} - -bool SWUnixSocket::bind(string path, SWBaseError *error) -{ - get_socket(); - - sockaddr_un myAdr; - - myAdr.sun_family = AF_UNIX; - strncpy(myAdr.sun_path, path.c_str(), path.size()+1); - - if(::bind(myfd, (sockaddr *)&myAdr, sizeof(myAdr)) == -1){ - handle_errno(error, "SWUnixSocket::bind() error: "); - return false; - } - - no_error(error); - return true; -} - -bool SWUnixSocket::connect(string path, SWBaseError *error) -{ - get_socket(); - - sockaddr_un remoteAdr; - - remoteAdr.sun_family = AF_UNIX; - strncpy(remoteAdr.sun_path, path.c_str(), path.size()+1); - - if(::connect(myfd, (sockaddr *)&remoteAdr, sizeof(remoteAdr)) == -1){ - handle_errno(error, "SWUnixSocket::connect() error: "); - return false; - } - - no_error(error); - return true; -} - -#endif /* __WIN32__ */ diff --git a/Server/sockets/sw_unix.h b/Server/sockets/sw_unix.h deleted file mode 100644 index 576f14c0..00000000 --- a/Server/sockets/sw_unix.h +++ /dev/null @@ -1,41 +0,0 @@ -// C++ Socket Wrapper -// SocketW Unix socket header -// -// Started 020316 -// -// License: LGPL v2.1+ (see the file LICENSE) -// (c)2002-2003 Anders Lindström - -/*********************************************************************** - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - ***********************************************************************/ - -#ifndef sw_unix_H -#define sw_unix_H -#ifndef __WIN32__ - -#include "sw_internal.h" -#include "sw_base.h" -#include - -// Simple streaming Unix class -class DECLSPEC SWUnixSocket : public SWBaseSocket -{ -public: - SWUnixSocket(block_type block=blocking); - ~SWUnixSocket(); - - // bind and connect to the socket file "path" - virtual bool bind(std::string path, SWBaseError *error = NULL); - virtual bool connect(std::string path, SWBaseError *error = NULL); - -protected: - virtual void get_socket(); - virtual SWBaseSocket* create(int socketdescriptor, SWBaseError *error); -}; - -#endif /* __WIN32__ */ -#endif /* sw_unix_H */ diff --git a/Server/user.cpp b/Server/user.cpp index 546aa3c3..6a15adf9 100644 --- a/Server/user.cpp +++ b/Server/user.cpp @@ -1,4 +1,20 @@ -#include "user.h" +#include "buffer.h" +#include "../sockets/SocketW.h" +#include + +class user{ + public: + user(); + ~user(); + void disconnect(); + void connect(SWBaseSocket * newConnection); + void Send(buffer ** ringbuf, int buffers); + bool is_connected; + SWUnixSocket * Conn; + int MyBuffer; + int MyBuffer_num; +};//user + user::user() { Conn = NULL; @@ -37,12 +53,12 @@ void user::Send(buffer ** ringbuf, int buffers){ return; } SWBaseSocket::SWBaseError err; - int ret = Conn->fsend(ringbuf[MyBuffer]->data, ringbuf[MyBuffer]->size, &err); + int ret = Conn->fsend(ringbuf[MyBuffer]->FLV->data, ringbuf[MyBuffer]->FLV->len, &err); if ((err != SWBaseSocket::ok) && (err != SWBaseSocket::notReady)){ disconnect(); return; } - if (ret == ringbuf[MyBuffer]->size){ + if (ret == ringbuf[MyBuffer]->FLV->len){ //completed a send - switch to next buffer MyBuffer++; MyBuffer %= buffers; diff --git a/Server/user.h b/Server/user.h deleted file mode 100644 index 775d034f..00000000 --- a/Server/user.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include "buffer.h" -#include "sockets/SocketW.h" -#include - -class user{ - public: - user(); - ~user(); - void disconnect(); - void connect(SWBaseSocket * newConnection); - void Send(buffer ** ringbuf, int buffers); - bool is_connected; - SWUnixSocket * Conn; - int MyBuffer; - int MyBuffer_num; -};//user - diff --git a/Client/sockets/SocketW.h b/sockets/SocketW.h similarity index 100% rename from Client/sockets/SocketW.h rename to sockets/SocketW.h diff --git a/Client/sockets/sw_base.cpp b/sockets/sw_base.cpp similarity index 100% rename from Client/sockets/sw_base.cpp rename to sockets/sw_base.cpp diff --git a/Client/sockets/sw_base.h b/sockets/sw_base.h similarity index 100% rename from Client/sockets/sw_base.h rename to sockets/sw_base.h diff --git a/Client/sockets/sw_inet.cpp b/sockets/sw_inet.cpp similarity index 100% rename from Client/sockets/sw_inet.cpp rename to sockets/sw_inet.cpp diff --git a/Client/sockets/sw_inet.h b/sockets/sw_inet.h similarity index 100% rename from Client/sockets/sw_inet.h rename to sockets/sw_inet.h diff --git a/Client/sockets/sw_internal.h b/sockets/sw_internal.h similarity index 100% rename from Client/sockets/sw_internal.h rename to sockets/sw_internal.h diff --git a/Client/sockets/sw_unix.cpp b/sockets/sw_unix.cpp similarity index 100% rename from Client/sockets/sw_unix.cpp rename to sockets/sw_unix.cpp diff --git a/Client/sockets/sw_unix.h b/sockets/sw_unix.h similarity index 100% rename from Client/sockets/sw_unix.h rename to sockets/sw_unix.h diff --git a/util/flv.cpp b/util/flv.cpp new file mode 100644 index 00000000..f374c8d5 --- /dev/null +++ b/util/flv.cpp @@ -0,0 +1,69 @@ +#include //for read() + +struct FLV_Pack { + int len; + int buf; + char * data; +};//FLV_Pack + +char FLVHeader[13]; + +//reads full length from a file descriptor +void Magic_Read(char * buf, int len, int file){ + int i = 0; + while (i < len) i += read(file, buf, len-i); +} + + +//reads a FLV header and checks for correctness +//returns true if everything is alright, false otherwise +bool FLV_Readheader(int file){ + Magic_Read(FLVHeader,13,file); + if (FLVHeader[0] != 'F') return false; + if (FLVHeader[1] != 'L') return false; + if (FLVHeader[2] != 'V') return false; + if (FLVHeader[8] != 0x09) return false; + if (FLVHeader[9] != 0) return false; + if (FLVHeader[10] != 0) return false; + if (FLVHeader[11] != 0) return false; + if (FLVHeader[12] != 0) return false; + return true; +}//FLV_Readheader +bool FLV_Readheader(){ + fread(FLVHeader,1,13,stdin); + if (FLVHeader[0] != 'F') return false; + if (FLVHeader[1] != 'L') return false; + if (FLVHeader[2] != 'V') return false; + if (FLVHeader[8] != 0x09) return false; + if (FLVHeader[9] != 0) return false; + if (FLVHeader[10] != 0) return false; + if (FLVHeader[11] != 0) return false; + if (FLVHeader[12] != 0) return false; + return true; +}//FLV_Readheader + +//gets a packet, storing in given FLV_Pack pointer. +//will assign pointer if null +//resizes FLV_Pack data field bigger if data doesn't fit +// (does not auto-shrink for speed!) +void FLV_GetPacket(FLV_Pack *& p, int file){ + if (!p){p = (FLV_Pack*)calloc(1, sizeof(FLV_Pack));} + if (p->buf < 15){p->data = (char*)realloc(p->data, 15); p->buf = 15;} + Magic_Read(p->data,11,file); + p->len = p->data[3] + 15; + p->len += (p->data[2] << 8); + p->len += (p->data[1] << 16); + if (p->buf < p->len){p->data = (char*)realloc(p->data, p->len);} + Magic_Read(p->data+11,p->len-11,file); +}//FLV_GetPacket + +void FLV_GetPacket(FLV_Pack *& p){ + if (!p){p = (FLV_Pack*)calloc(1, sizeof(FLV_Pack));} + if (p->buf < 15){p->data = (char*)realloc(p->data, 15); p->buf = 15;} + fread(p->data,1,11,stdin); + p->len = p->data[3] + 15; + p->len += (p->data[2] << 8); + p->len += (p->data[1] << 16); + if (p->buf < p->len){p->data = (char*)realloc(p->data, p->len);} + fread(p->data+11,1,p->len-11,stdin); +}//FLV_GetPacket