#include #include #include #include #include #include #include #include #include "disp.h" #include "log.h" #include "public.h" #include "server.h" struct waitClientArgs { sockaddr_in newSockAddr; socklen_t newSockAddrSize; int auxInt; // used in client mode because I didn't want to make another // struct to keep track of }; void * waitForClient(void *argss) { waitClientArgs *args = static_cast(argss); clientSocketDescriptor = accept(serverSocketDescriptor, (sockaddr *)&args->newSockAddr, &args->newSockAddrSize); if (clientSocketDescriptor >= 0) { writeToFile(logFileName, "client connected"); if (linesInFile(logFileName) > LOG_LENGTH) linePos++; displayFile(logFileName, linePos, LOG_LENGTH); } delete args; // delete to avoid memory leaks return pollForClient(); } void * pollForClient() { char msg[1024]; while (1) { client_message_loop: // receive a message from the client (listen) memset(&msg, 0, sizeof(msg)); // clear the buffer bytesRead += recv(clientSocketDescriptor, (char *)&msg, sizeof(msg), 0); if (msg[0] == '\0') goto client_message_loop; writeToFile(logFileName, msg); if (linesInFile(logFileName) > LOG_LENGTH) linePos++; displayFile(logFileName, linePos, LOG_LENGTH); } return nullptr; } // set up a suitable server for this int setupServer(int port) { // setup a socket and connection tools sockaddr_in servAddr; bzero((char *)&servAddr, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.sin_port = htons(port); // open stream oriented socket with internet address // also keep track of the socket descriptor serverSocketDescriptor = socket(AF_INET, SOCK_STREAM, 0); if (serverSocketDescriptor < 0) { // keeps from bricking the terminal if this happens endwin(); fprintf(stderr, "Error establishing the server socket!\n"); exit(0); } // bind the socket to its local address int bindStatus = bind(serverSocketDescriptor, (struct sockaddr *)&servAddr, sizeof(servAddr)); if (bindStatus < 0) { // keeps from bricking the terminal if this happens endwin(); fprintf(stderr, "Error binding socket to local address!\n"); exit(0); } writeToFile(logFileName, "Waiting for a client to connect..."); // listen for up to 5 requests at a time listen(serverSocketDescriptor, 5); // receive a request from client using accept // we need a new address to connect with the client sockaddr_in newSockAddr; socklen_t newSockAddrSize = sizeof(newSockAddr); // accept, create a new socket descriptor to // handle the new connection with client auto *aaa = new waitClientArgs{}; // it looks stupid but it works aaa->newSockAddr = newSockAddr; aaa->newSockAddrSize = newSockAddrSize; int rc = pthread_create(&client_wait_thread, nullptr, waitForClient, aaa); pthread_detach(client_wait_thread); writeToFile(logFileName, "Server started successfully"); gettimeofday(&start1, NULL); return 0; } void closeServer() { long e = end1.tv_sec - start1.tv_sec; /* the linter freaks out if you don't save it as a variable */ // we need to close the socket descriptors after we're all done gettimeofday(&end1, NULL); close(clientSocketDescriptor); close(serverSocketDescriptor); /* Don't just die silently */ puts("********Session********"); printf("Bytes written: %i\n", bytesWritten); printf("Bytes read: %i\n", bytesRead); printf("Elapsed time: %ld secs\n", e); puts("Connection closed."); }