// ====================================================================== // // 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"); }