From 530014a3cce53e86dce8917e98a4e86d02f176aa Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 26 Apr 2007 15:06:49 +0000 Subject: Merged Ito and put it in the BU namespace. I should probably clean up the formatting on the comments, some of the lines wrap, but I'm not too worried about it right now. I also fixed up the doxygen config and build.conf files so that everything is building nice and smooth now. --- src/serversocket.cpp | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/serversocket.cpp (limited to 'src/serversocket.cpp') diff --git a/src/serversocket.cpp b/src/serversocket.cpp new file mode 100644 index 0000000..c53c80d --- /dev/null +++ b/src/serversocket.cpp @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "serversocket.h" +#include "exceptions.h" + +Bu::ServerSocket::ServerSocket( int nPort, int nPoolSize ) : + nPort( nPort ) +{ + /* Create the socket and set it up to accept connections. */ + struct sockaddr_in name; + + /* Give the socket a name. */ + name.sin_family = AF_INET; + name.sin_port = htons( nPort ); + + // I think this specifies who we will accept connections from, + // a good thing to make configurable later on + name.sin_addr.s_addr = htonl( INADDR_ANY ); + + startServer( name, nPoolSize ); +} + +Bu::ServerSocket::ServerSocket(const FString &sAddr,int nPort, int nPoolSize) : + nPort( nPort ) +{ + /* Create the socket and set it up to accept connections. */ + struct sockaddr_in name; + + /* Give the socket a name. */ + name.sin_family = AF_INET; + name.sin_port = htons( nPort ); + + inet_aton( sAddr.getStr(), &name.sin_addr ); + + startServer( name, nPoolSize ); +} + +Bu::ServerSocket::~ServerSocket() +{ +} + +void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) +{ + /* Create the socket. */ + nServer = socket( PF_INET, SOCK_STREAM, 0 ); + if( nServer < 0 ) + { + throw Bu::SocketException("Couldn't create a listen socket."); + } + + int opt = 1; + setsockopt( + nServer, + SOL_SOCKET, + SO_REUSEADDR, + (char *)&opt, + sizeof( opt ) + ); + + if( bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 ) + { + throw Bu::SocketException("Couldn't bind to the listen socket."); + } + + if( listen( nServer, nPoolSize ) < 0 ) + { + throw Bu::SocketException( + "Couldn't begin listening to the server socket." + ); + } + + FD_ZERO( &fdActive ); + /* Initialize the set of active sockets. */ + FD_SET( nServer, &fdActive ); +} + +int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) +{ + fd_set fdRead = fdActive; + + struct timeval xT; + + xT.tv_sec = nTimeoutSec; + xT.tv_usec = nTimeoutUSec; + + if( TEMP_FAILURE_RETRY(select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 ) + { + throw SocketException( + "Error scanning for new connections: %s", strerror( errno ) + ); + } + + if( FD_ISSET( nServer, &fdRead ) ) + { + struct sockaddr_in clientname; + size_t size; + int nClient; + + size = sizeof( clientname ); +#ifdef __CYGWIN__ + nClient = ::accept( nServer, (struct sockaddr *)&clientname, + (int *)&size + ); +#else + nClient = ::accept( nServer, (struct sockaddr *)&clientname, &size ); +#endif + if( nClient < 0 ) + { + throw SocketException( + "Error accepting a new connection: %s", strerror( errno ) + ); + } + char tmpa[20]; + inet_ntop( AF_INET, (void *)&clientname.sin_addr, tmpa, 20 ); + //"New connection from host %s, port %hd.", + // tmpa, ntohs (clientname.sin_port) ); + + { + int flags; + + flags = fcntl( nClient, F_GETFL, 0 ); + flags |= O_NONBLOCK; + if( fcntl( nClient, F_SETFL, flags ) < 0) + { + throw SocketException( + "Error setting option on client socket: %s", + strerror( errno ) + ); + } + } + + return nClient; + } + + return -1; +} + -- cgit v1.2.3