diff options
author | Matthias P. Braendli (think) <matthias@mpb.li> | 2013-11-08 14:43:19 +0100 |
---|---|---|
committer | Matthias P. Braendli (think) <matthias@mpb.li> | 2013-11-08 14:43:19 +0100 |
commit | c5306f81a9d3b87df7e16c852f2505ac913193ca (patch) | |
tree | 40716835305aa871cae5a5b3c805f0c673f47108 /src/dabOutput/dabOutputTcp.cpp | |
parent | 573c7b63092618ecae86847d9d0a143801db0780 (diff) | |
download | dabmux-c5306f81a9d3b87df7e16c852f2505ac913193ca.tar.gz dabmux-c5306f81a9d3b87df7e16c852f2505ac913193ca.tar.bz2 dabmux-c5306f81a9d3b87df7e16c852f2505ac913193ca.zip |
make dabOutput more object-oriented
Diffstat (limited to 'src/dabOutput/dabOutputTcp.cpp')
-rw-r--r-- | src/dabOutput/dabOutputTcp.cpp | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/dabOutput/dabOutputTcp.cpp b/src/dabOutput/dabOutputTcp.cpp new file mode 100644 index 0000000..a3d7a5a --- /dev/null +++ b/src/dabOutput/dabOutputTcp.cpp @@ -0,0 +1,154 @@ +#include <cstring> +#include <cstdio> +#include <signal.h> +#include <limits.h> +#include "dabOutput.h" +#include "TcpServer.h" + +#ifdef _WIN32 +# include <io.h> +# ifdef __MINGW32__ +# define FS_DECLARE_CFG_ARRAYS +# include <winioctl.h> +# endif +# include <sdci.h> +#else +# include <unistd.h> +# include <sys/time.h> +# ifndef O_BINARY +# define O_BINARY 0 +# endif // O_BINARY +#endif + +void* tcpThread(void* param) +{ + TcpSocket* client; + + DabOutputTcp* tcp = (DabOutputTcp*)param; + + while ((client = tcp->server->accept()) != NULL) { + etiLog.print(TcpLog::INFO, "TCP server got a new client.\n"); + if (tcp->client != NULL) { + delete tcp->client; + } + tcp->client = client; + } + etiLog.print(TcpLog::ERR, "TCP thread can't accept new client (%s)\n", + inetErrDesc, inetErrMsg); + + return NULL; +} + +int DabOutputTcp::Open(const char* name) +{ + char* hostport = strdup(name); // the name is actually an tuple host:port + + char* address; + long port; + address = strchr((char*)hostport, ':'); + if (address == NULL) { + etiLog.printHeader(TcpLog::ERR, + "\"%s\" is an invalid format for tcp address: " + "should be [address]:port - > aborting\n", + hostport); + goto tcp_open_fail; + } + + // terminate string hostport after the host, and advance address to the port number + *(address++) = 0; + + port = strtol(address, (char **)NULL, 10); + if ((port == LONG_MIN) || (port == LONG_MAX)) { + etiLog.printHeader(TcpLog::ERR, + "can't convert port number in tcp address %s\n", address); + goto tcp_open_fail; + } + if (port == 0) { + etiLog.printHeader(TcpLog::ERR, + "can't use port number 0 in tcp address\n"); + goto tcp_open_fail; + } + address = hostport; + if (strlen(address) > 0) { + if (this->server->create(port, address) == -1) { + etiLog.printHeader(TcpLog::ERR, "Can't create Tcp server on %s:%i " + "(%s: %s) -> aborting\n", + address, port, inetErrDesc, inetErrMsg); + goto tcp_open_fail; + } + } else { + if (this->server->create(port) == -1) { + etiLog.printHeader(TcpLog::ERR, "Can't create Tcp server on :%i " + "(%s: %s) -> aborting\n", + port, inetErrDesc, inetErrMsg); + goto tcp_open_fail; + } + } + + //sprintf(name, "%s:%i", this->packet_->getAddress().getHostAddress(), + // this->packet_->getAddress().getPort()); + + if (this->server->listen() == -1) { + etiLog.printHeader(TcpLog::ERR, "Can't listen on Tcp socket (%s: %s)\n", + inetErrDesc, inetErrMsg); + goto tcp_open_fail; + } +#ifdef _WIN32 + this->thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tcpThread, this, 0, NULL); + if (this->thread_ == NULL) { + fprintf(stderr, "Can't create TCP child"); + goto tcp_open_fail; + } +#else + if (pthread_create(&this->thread_, NULL, tcpThread, this)) { + perror("Can't create TCP child"); + goto tcp_open_fail; + } +#endif + + return 0; + +tcp_open_fail: + free(hostport); + return -1; +} + + +int DabOutputTcp::Write(void* buffer, int size) +{ + + if (this->client != NULL) { + if (this->client->write(&size, 2) == 2) { + if (this->client->write(buffer, size) != size) { + return size; + } + } + else { + etiLog.print(TcpLog::INFO, "TCP server client disconnected.\n"); + delete this->client; + this->client = NULL; + } + } + return size; +} + + +int DabOutputTcp::Close() +{ + this->server->close(); + if( this->client != NULL ) + this->client->close(); +#ifdef WIN32 + DWORD status; + for (int i = 0; i < 5; ++i) { + if (GetExitCodeThread(this->thread_, &status)) { + break; + } + Sleep(100); + } + TerminateThread(this->thread_, 1); +#else + pthread_kill(this->thread_, SIGPIPE); +#endif + return 0; +} |