From 3d8ce593278ab27774d9bb149ae520b0dfc22e1b Mon Sep 17 00:00:00 2001 From: cdez Date: Wed, 19 Feb 2025 19:33:45 -0700 Subject: [PATCH] Finished? assignment 2. Needs to be tested with multiple clients, but also for the original client connection. --- echoserver/echoserver.c | 175 ++++++++++++++++++++++++++-------------- echoserver/echoserver.h | 2 + 2 files changed, 116 insertions(+), 61 deletions(-) diff --git a/echoserver/echoserver.c b/echoserver/echoserver.c index 0722e53..1533724 100644 --- a/echoserver/echoserver.c +++ b/echoserver/echoserver.c @@ -34,10 +34,9 @@ int main(int argc, char **argv) } // 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)); + 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)); - // CODE HERE // bind the TCP socket to port 8888 / ECHOPORT serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = INADDR_ANY; @@ -48,76 +47,130 @@ int main(int argc, char **argv) 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) - // { - // int clientAddrLen; - // int receivedDataLen; - // // grab the data from the client - // receivedDataLen = recvfrom(socketEchoFD, message, BUFFER_SIZE, MSG_WAITALL, &clientAddr, &clientAddrLen); - // message[receivedDataLen] = '\0'; - // // if "01189998811991197253\r\n" is received, then close the server. - // if(strcmp(message, "01189998811991197253\n") == 0 || strcmp(message, "01189998811991197253\r\n") == 0) - // { - // // if the server recv'd the close command, then close the server. - // printf("\nServer received close.\n"); - // quitFlag = false; - // } - // // otherwise, repeat/echo back the message to the client. - // // setup the reply message - // char reply[BUFFER_SIZE]; - // // add the current time to the reply - // sprintf(reply, "%d", time(NULL)); - // // send the reply to the requestee - // sendto(socketEchoFD, (const char *)reply, strlen(reply), 0, (const struct sockaddr *)&clientAddr, clientAddrLen); - // // log the time command recv'd - // printf("\nServer received time. Replied with: %d\n", time(NULL)); - // } while (quitFlag) { - // 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) + // 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 accept from the client.\n"); + // + printf("\nUnable to select socket to listen to.\n"); return -1; } - else + // for loop that loops up to the max file descriptor. + for(int fileIter = 0; fileIter < maxFD; fileIter++) { - printf("\nConnection received from client.\n"); + // check to see if the file descriptor is in the set of sockets using FD_ISSET() + if(FD_ISSET(fileIter, &socketList)) + { + // 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; + } + } + } + // 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 = recv(fileIter, message, BUFFER_SIZE, 0); + // make sure that the connection is still open before attempting to send. + if(messageBytes <= 0) + { + // 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 + send(fileIter, message, sizeof(message), 0); + printf("\nMessage has been sent back to client.\n"); + } + } + } } - // grab the data from the client, save to message. - messageBytes = recv(clientEchoFD, message, BUFFER_SIZE, 0); - // if "01189998811991197253\r\n" is received, then close the server. - if (strcmp(message, "01189998811991197253\n") == 0 || strcmp(message, "01189998811991197253\r\n") == 0) - { - // if the server recv'd the close command, then close the server. - printf("\nServer received close.\n"); - quitFlag = false; - } - // otherwise, repeat/echo back the message to the client. - // NEW CODE HERE - // 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); + + // 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); diff --git a/echoserver/echoserver.h b/echoserver/echoserver.h index 5a19882..b1ef31c 100644 --- a/echoserver/echoserver.h +++ b/echoserver/echoserver.h @@ -9,12 +9,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include // data structures