Code:
// See header file.
SocketManager::SocketManager(const string bindIPAddr, const short bindPort, const short backLog) {
// Initializes the fields.
this->serverFD = -1;
this->connectionReactor = NULL;
// ####
int result;
sockaddr_in inAddr;
// Creates the server socket and stores its file descriptor. Forces the TCP
// protocol.
result = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// Determines if there was one or more errors creating the socket. If so,
// throw a critical exception.
if (-1 == result) {
throw CritException("Could not create socket.", __LINE__, __FILE__);
}
this->serverFD = result;
// Set the server socket as non-blocking. This will be inherited.
const int tmpFlags = fcntl(this->serverFD, F_GETFL, 0);
fcntl(this->serverFD, F_SETFL, tmpFlags | O_NONBLOCK);
// Set the server socket as reusible. This will be inherited.
const int on = 1;
result = setsockopt(this->serverFD, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&on), sizeof(on));
// Determines if there was an error setting the server socket option.
if (-1 == result) {
throw CritException("Could not set the server socket as reusible.", __LINE__, __FILE__);
}
// Begins storing the server address information.
inAddr.sin_family = AF_INET;
inAddr.sin_port = htons(bindPort);
result = inet_pton(AF_INET, bindIPAddr.c_str(), &(inAddr.sin_addr));
// Determines if there was an error storing the IP address in its Network
// Byte Order in the server information struct. If so, throw a critical
// exception.
if ((0 == result) || (-1 == result)) {
throw CritException("Could not convert the server's IP address to its NBO representation.", __LINE__, __FILE__);
}
// Zero-fills the sin_zero field.
memset(&(inAddr.sin_zero), 0, sizeof(char) * 8);
// Binds the server socket to the specified server address information.
result = bind(this->serverFD, reinterpret_cast<sockaddr *>(&inAddr), sizeof(inAddr));
// Determines if there was an error binding the server socket to the
// specified server address information. If so, throw a critical exception.
if (-1 == result) {
throw CritException("Could not bind the server socket to the server address information", __LINE__, __FILE__);
}
// ####
// Marks the server socket as accepting incoming connections.
result = listen(this->serverFD, backLog);
// Determines if there was an error marking the server socket. If so, throw
// a critical exception.
if (-1 == result) {
throw CritException("Could not mark the server socket as accepting incoming connections.", __LINE__, __FILE__);
}
// ####
// Creates a new ConnectionReactor nwo that the server socket has been
// created, bound, and marked for accepting incoming connections.
this->connectionReactor = new ConnectionReactor(this->serverFD);
}