#include #include #include #include #include #include #include #include #include #include #define LISTEN_PORT 1234 // Port we accept connections on #define BUFFER_SIZE 1024 // Size of buffer for receiving data /* Name: createTcpSocket * Description: Creates a new, unconnected TCP socket * Parameters: sock - buffer to receive socket * Return code: true if successful * false if an error occurred */ bool createTcpSocket(int *sock) { bool failed = false; *sock = socket(AF_INET, SOCK_STREAM, 0); if (*sock == -1) { fprintf(stderr, "Couldn't create socket: %s\n", strerror(errno)); failed = true; } return !failed; } /* Name: bindTcpSocket * Description: Binds a TCP socket to a specific port on all interfaces * Parameters: sock - socket to bind * port - port to bind socket to * Return code: true if successful * false if an error occurred */ bool bindTcpSocket(int sock, unsigned short port) { bool result = false; struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(port); saddr.sin_addr.s_addr = INADDR_ANY; printf("Binding to %s:%u...", inet_ntoa(saddr.sin_addr), port); fflush(stdout); if (bind(sock, (struct sockaddr*) &saddr, sizeof(saddr)) == 0) { printf(" OK.\n"); result = true; } else { printf(" FAILED.\n"); fprintf(stderr, "Couldn't bind socket: %s\n", strerror(errno)); } return result; } /* Name: setSocketToListenMode * Description: Sets a bound TCP socket to listen mode * Parameters: sock - socket to set to listen mode * Return code: true if successful * false if an error occurred */ bool setSocketToListenMode(int sock) { bool failed = false; if (listen(sock, 3) == -1) { fprintf(stderr, "Couldn't set socket to listen mode: %s\n", strerror(errno)); failed = true; } return !failed; } /* Name: acceptClient * Description: Accepts a new client on a socket in listen mode * Parameters: sock - socket in listen mode * client - buffer for socket of new client * Return code: true if successful * false if an error occurred */ bool acceptClient(int sock, int *client) { bool result = false; struct sockaddr_in saddr; socklen_t size = sizeof(saddr); *client = accept(sock, (struct sockaddr*) &saddr, &size); if (*client >= 0) { printf("Got a new client from %s:%u.\n", inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); result = true; } else { fprintf(stderr, "Accepting client failed: %s\n", strerror(errno)); } return result; } /* Name: receiveString * Description: Receives and prints a string from a connected socket * Parameters: sock - socket to read from * Return code: true if successful * false if an error occurred */ bool receiveString(int sock) { int total = 0; bool done = false; bool failed = false; char buffer[BUFFER_SIZE]; while (!done && !failed) { int bytes = recv(sock, buffer + total, sizeof(buffer) - total - 1, 0); if (bytes > 0) { total += bytes; buffer[total] = '\0'; } else if (bytes == 0) { done = true; } else if (bytes == -1) { fprintf(stderr, "Couldn't read from socket: %s\n", strerror(errno)); failed = true; } } if (!failed) { printf("Received %i bytes: <%s>\n", total, buffer); } return !failed; } /* Name: safeCloseSocket * Description: Checks if a socket is valid, closes it. The socket is * set to an invalid value to avoid double free errors. * Parameters: sock - socket to communicate with * Return code: none */ void safeCloseSocket(int *sock) { if (*sock != -1) { close(*sock); *sock = -1; } } int main(void) { int sock = -1; bool good = createTcpSocket(&sock); if (good) good = bindTcpSocket(sock, LISTEN_PORT); if (good) good = setSocketToListenMode(sock); int client = -1; if (good) good = acceptClient(sock, &client); if (good) good = receiveString(client); safeCloseSocket(&client); safeCloseSocket(&sock); return good ? EXIT_SUCCESS : EXIT_FAILURE; }