// ======================================================================
//
// Simple socket class code
//
// Stream sockets only, but datagrams could be added.
//
// Lots could be done here. For example, all of the reading and writing
// for a socket could be handled in the class, as well as informational
// services, timers, broadcasts and basically everything else. The
// following is simply for the purposes of demonstration.
//
// ======================================================================
#include "socket_class.h"
// ======================================================================
// ServerSocket Methods
// =====================================================
//
// Open a server socket for a stream connection.
//
// ======================================================
ServerSocket::ServerSocket (int port)
{
int lsock;
sockaddr_in addr;
error = 0;
// Open a socket
lsock = socket (AF_INET, SOCK_STREAM, 0);
if (lsock == -1)
{
error = SOCKET_OPEN_FAIL;
return;
}
// Bind the socket to the local port and set it up to
// listen.
bzero ((char *) &addr, sizeof (addr));
addr . sin_family = AF_INET;
addr . sin_port = htons ((short) port);
addr . sin_addr . s_addr = htonl (INADDR_ANY);
if (bind (lsock, (const sockaddr *) &addr, sizeof (addr)) < 0)
{
error = SOCKET_BIND_FAIL;
sock = -1;
close (lsock);
return;
}
// Do the listen. This is actually not a good place for this, since the
// listen should be handled by the application which is in a better
// position to know when it is time to listen.
if ((listen (lsock, 5)) < 0)
{
error = SOCKET_LISTEN_FAIL;
sock = -1;
close (lsock);
return;
}
// Save the socket number in the class private variable.
sock = lsock;
}
// ============================================================
//
// Accept and connection and create a new socket for the client.
//
// =============================================================
Socket ServerSocket::Accept ()
{
int newsock;
sockaddr addr;
int addr_len;
error = 0;
// Do the accept, and when it returns, return the new Socket
// for use by the server.
newsock = accept (sock, &addr, &addr_len);
Socket s = Socket (newsock);
return (s);
}
// =====================================================================
//
// Return the socket number for use by the program.
//
// =====================================================================
int ServerSocket::GetSocketNum ()
{
error = 0;
return (sock);
}
void ServerSocket::Close ()
{
error = 0;
shutdown (sock, 2);
close (sock);
}
// =====================================================================
//
// Return the current error code for the socket.
//
// =====================================================================
int ServerSocket::Error ()
{
return (error);
}
// =====================================================================
//
// Return an error message for the current error. Not finished.
//
// =====================================================================
char *ServerSocket::ErrorMessage ()
{
return ("Some kind of error");
}
// Socket Methods ========================================================
// ===============================================================
//
// Open a client or peer socket for a stream connection.
//
// ================================================================
Socket::Socket (char *host, int port)
{
sockaddr_in addr;
int lsock;
unsigned int iaddr;
hostent *hostent;
error = 0;
// Open a socket
lsock = socket (AF_INET, SOCK_STREAM, 0);
if (lsock == -1)
{
error = SOCKET_OPEN_FAIL;
return;
}
// Set up an address and connect.
hostent = gethostbyname (host);
if (hostent == NULL)
{
error = DNS_DB_ERROR;
close (lsock);
sock = -1;
return;
}
addr.sin_family = AF_INET;
addr.sin_port = htons (port);
memcpy (&iaddr, hostent->h_addr_list[0], 4);
addr . sin_addr . s_addr = iaddr;
if (connect(lsock, (sockaddr *) &addr, sizeof (struct sockaddr_in)) == -1)
{
error = SOCKET_CONNECT_FAIL;
close (lsock);
Socket::sock = -1;
return;
}
Socket::sock = lsock;;
}
// ====================================================================
//
// Create a socket for an already open file descriptor (as from accept)
//
// =====================================================================
Socket::Socket (int lsock)
{
sockaddr_in addr;
// For a socket opened by the system where you just need the class
// to support the methods.
sock = lsock;
}
// =====================================================================
//
// Return the socket number for use by the program.
//
// =====================================================================
int Socket::GetSocketNum ()
{
error = 0;
return (sock);
}
// =====================================================================
//
// Shutdown and close the socket.
//
// =====================================================================
void Socket::Close ()
{
error = 0;
shutdown (Socket::sock, 2);
close (Socket::sock);
}
// =====================================================================
//
// Return the current error code for the socket.
//
// =====================================================================
int Socket::Error ()
{
return (error);
}
// =====================================================================
//
// Return an error message for the current error. Not finished.
//
// =====================================================================
char *Socket::ErrorMessage ()
{
return ("Some kind of error");
}