TcpServer.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 $Header$
00004 
00005 */
00006 
00007 #include <stdio.h>
00008 #include <unistd.h>
00009 #include <fcntl.h>
00010 
00011 #include "Error.h"
00012 #include "Core.h"
00013 
00014 #include "TcpServer.h"
00015 
00016 // Public methods.
00017 
00018 TcpServer::TcpServer(const String &bindAddress, const String &service) : Socket()
00019 {
00020   int t = 1;
00021   int res;
00022 
00023   if (FAILED(res = failureCode())) {
00024     ERROR_BACKTRACE(res);
00025     return;
00026   }
00027 
00028   if (FAILED(res = Connection::setAddress(CSTRING(bindAddress), CSTRING(service), "tcp", &_addr))) {
00029     failure(ERROR_BACKTRACE(res));
00030     return;
00031   }
00032 
00033   if ((_socket = ::socket(AF_INET, SOCK_STREAM, 0)) < 0) {
00034     failure(ERROR(MSG_SOCKET_CANNOT_CREATE, strerror(errno)));
00035     return;
00036   }
00037 
00038   if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(t))) {
00039     failure(ERROR(MSG_SOCKET_CANNOT_SET_OPTION, strerror(errno)));
00040     return;
00041   }
00042 
00043   if (bind(_socket, (struct sockaddr *)&(_addr), sizeof(_addr))) {
00044     failure(ERROR(MSG_SOCKET_CANNOT_BIND, strerror(errno)));
00045     return;
00046   }
00047 
00048   if (listen(_socket, TCP_SERVER_CONNECTION_QUEUE_SIZE)) {
00049     failure(ERROR(MSG_SOCKET_CANNOT_LISTEN, strerror(errno)));
00050     return;
00051   }
00052 
00053   if (FAILED(res = CORE()->add(this))) {
00054     failure(ERROR_BACKTRACE(res));
00055     return;
00056   }
00057 }
00058 
00059 TcpServer::~TcpServer()
00060 {
00061   int res;
00062 
00063   if (FAILED(res = CORE()->remove(this)))
00064     ERROR_BACKTRACE(res);
00065 
00066   if (::shutdown(_socket, SHUT_RDWR) != 0)
00067     ERROR(MSG_SOCKET_CANNOT_SHUTDOWN, strerror(errno));
00068 
00069   if (::close(_socket) != 0)
00070     ERROR(MSG_SOCKET_CANNOT_CLOSE, strerror(errno));
00071 }
00072 
00073 int TcpServer::accept(TcpConnection **connection)
00074 {
00075   int connectionSocket;
00076   struct sockaddr_in clientAddr;
00077   socklen_t clientLen = sizeof(clientAddr);
00078   int res;
00079 
00080   if (!connection)
00081     return ERROR(MSG_NULL_POINTER);
00082 
00083   *connection = NULL;
00084 
00085   if ((connectionSocket = ::accept(_socket, (struct sockaddr *)&clientAddr, &clientLen)) < 0)
00086     return ERROR(MSG_SOCKET_CANNOT_ACCEPT_CONNECTION, strerror(errno));
00087 
00088   if (!(*connection = new TcpConnection(connectionSocket, &clientAddr)))
00089     return ERROR(MSG_OBJECT_CANNOT_CREATE, "TcpConnection");
00090   if (FAILED(res = (*connection)->failureCode())) {
00091     delete connection;
00092     return ERROR_BACKTRACE(res);
00093   }
00094 
00095   EMIT(accepted, *connection);
00096 
00097   if (FAILED(res = (*connection)->setConnected()))
00098     return ERROR_BACKTRACE(res);
00099 
00100   return OK;
00101 }
00102 

Generated on Thu Sep 6 20:11:25 2007 for Pylon Application Platform by  doxygen 1.5.1