// header files #include "echoserver.h" // constants // echoserver port is 8888 #define ECHOPORT 8888 #define BUFFER_SIZE 1024 #define MAX_CONNECT_QUEUE 10 // prototypes // main function int main(int argc, char **argv) { // initialize program (variables and structs) bool quitFlag = true; int socketEchoFD; int clientEchoFD; int reuseAddrOpt = 1; int keepAliveOpt = 1; char message[BUFFER_SIZE]; int messageBytes; struct sockaddr_in serverAddr; struct sockaddr_storage clientAddr; socklen_t clientSize; memset(&serverAddr, 0, sizeof(serverAddr)); memset(&clientAddr, 0, sizeof(clientAddr)); // define a TCP socket socketEchoFD = socket(AF_INET, SOCK_STREAM, 0); if(socketEchoFD < 0) { printf("Unable to create the socket.\n"); return -1; } // use the setsockopt function to make the socket accept different configurations // allow for the reuse of the address/bind. setsockopt(socketEchoFD, SOL_SOCKET, SO_REUSEADDR, &reuseAddrOpt, sizeof(reuseAddrOpt)); // also need to set the socket to keepalive using setsockopt setsockopt(socketEchoFD, SOL_SOCKET, SO_KEEPALIVE, &keepAliveOpt, sizeof(keepAliveOpt)); // bind the TCP socket to port 8888 / ECHOPORT serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = INADDR_ANY; serverAddr.sin_port = htons(ECHOPORT); int bindCheck = bind(socketEchoFD, &serverAddr, sizeof(serverAddr)); if(bindCheck < 0) { printf("Unable to bind the socket to the port or address.\n Is either in use?"); return -1; } // use fnctl to set the non-blocking flag for the socket // CODE HERE fcntl(socketEchoFD, F_SETFL, O_NONBLOCK); // the server will now accept client connections by listening. listen(socketEchoFD, MAX_CONNECT_QUEUE); // create a file descriptor set, to keep track of the sockets in use using fd_set and FD_ZERO? // CODE HERE fd_set socketList; FD_ZERO(&socketList); // add the socketEchoFD to the file descriptor set using fd_set // CODE HERE FD_SET(socketEchoFD, &socketList); // somehow have a max file descriptor, set this? // CODE HERE int maxFD = socketEchoFD; // while loop that will continue to listen for messages from clients. printf("Echoserver listening on port: %d\n", ECHOPORT); while (quitFlag) { // somehow use the set of file descriptor sockets here // CODE HERE // use the select() function here to check the set of sockets // CODE HERE int selectedFD = select(maxFD+1, &socketList, NULL, NULL, NULL); // check to make sure select() didn't error out. // CODE HERE if(selectedFD == -1) { // printf("\nUnable to select socket to listen to.\n"); return -1; } // for loop that loops up to the max file descriptor. for(int fileIter = 0; fileIter <= maxFD; fileIter++) { // check to see if the file descriptor is in the set of sockets using FD_ISSET() if(FD_ISSET(fileIter, &socketList)) { printf("\nSocket has been found: %d\n", fileIter); // if the server socket is being written to/read from, if(fileIter == socketEchoFD) { // create a client socket using accept clientSize = sizeof(clientAddr); clientEchoFD = accept(socketEchoFD, &clientAddr, &clientSize); // check to see if the client socket is connected (-1) if(clientEchoFD == -1) { printf("\nCould not connect the client to a socket.\n"); return -1; } else { // set the non blocking flag using fnctl fcntl(clientEchoFD, F_SETFL, O_NONBLOCK); // add the client socket to the set of file descriptor sockets FD_SET(clientEchoFD, &socketList); // check to see if the new socket FD is greater than the current max (clientSocket > maxFD) if(clientEchoFD > maxFD) { // if it is, set the new max. maxFD = clientEchoFD; } printf("\nConnected client to socket: %d\n", clientEchoFD); } printf("\nAccepted connection from new client.\n"); } // if the client socket(s) are being written to/read from, else { // grab the size of the listening client (not needed?) // grab the client's socket information (not needed?) // check to see if the client socket is actually connected (not needed?) // grab the data from the client, save to message. messageBytes = read(fileIter, message, BUFFER_SIZE); // make sure that the connection is still open before attempting to send. if(messageBytes == 0) // old: messageBytes <= 0 { printf("\nmessageBytes: %d\n", messageBytes); // if it is not open, close the socket and remove the socket from the socket list using FD_CLR() close(fileIter); FD_CLR(fileIter, &socketList); printf("\nClient has closed connection.\n"); } else { // if it is open, send the message back to the client over the client socket write(fileIter, message,messageBytes); printf("\nMessage has been sent back to client.\n"); } printf("\nMessage received.\n"); } } } // OLD CODE HERE // // grab the size of the listened clients // clientSize = sizeof(clientAddr); // // grab the client's socket information // clientEchoFD = accept(socketEchoFD, &clientAddr, &clientSize); // // check to see if the client socket is actually connected // if(clientEchoFD == -1) // { // printf("\nUnable to accept from the client.\n"); // return -1; // } // else // { // printf("\nConnection received from client.\n"); // } // // grab the data from the client, save to message. // messageBytes = recv(clientEchoFD, message, BUFFER_SIZE, 0); // // otherwise, repeat/echo back the message to the client. // // make sure that the connection is still open before attempting to send. // if(messageBytes <= 0) // { // printf("\nERROR\n"); // // this means that the connection is closed, or had another error. // return -1; // } // else // { // // send back the message over the clientEcho socket. // send(clientEchoFD, message, sizeof(message), 0); // printf("\nMessage has been sent back to client.\n"); // } // // close the accepted listening socket since it is no longer needed. // close(clientEchoFD); // END OLD CODE HERE } // close the socket close(socketEchoFD); // profit??? return 0; } // function definitions /* Name: ??? Process: ??? Function Input/Parameters: ??? Function Output/Parameters: ??? Function Output/Returned: ??? Device Input/Device: ??? Device Output/Device: ??? Dependencies: ??? */