dieServer.cpp

URL: https://mirkwood.cs.edinboro.edu/~bennett/class/cmsc4000/spring2026/notes/ch3/code/dieServer.cpp
 
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <sys/un.h>  // need this for unix domain sockets.
#include <unistd.h> // unlink

#include <stdio.h>

#include <sstream>

using namespace std;

const string PATH{"/tmp/DieServer"};
const size_t BUFFER_SIZE {1024};

int main() {

     srand(time(nullptr));

     int theSocket;
     struct sockaddr_un address;

     theSocket = socket(AF_UNIX, SOCK_DGRAM, 0);

     if(theSocket == -1) {
        perror("Socket failed: ");
        exit(1);
     }

     // try to remove the an existing socket address
     if (-1 == unlink(PATH.c_str()) and errno != ENOENT) {
        perror("Unlink existing socket: ");
        exit(1);
     }

     // set the address field
     memset(&address, 0, sizeof(struct sockaddr_un));
     address.sun_family = AF_UNIX;
     // yuck  reinterpret_cast, But this is what is was built for.
     strncpy(address.sun_path, PATH.c_str(), sizeof(address.sun_path)-1);
     if( -1 == bind(theSocket,reinterpret_cast<struct sockaddr *>( &address),                 sizeof(struct sockaddr_un))) {
         perror("Bind failed: ");
     }

     bool done{false};
     char buffer[BUFFER_SIZE];     
     socklen_t len;
     size_t bytes;

     while (not done) {
         len = sizeof(struct sockaddr_un);
         struct sockaddr_un clientAddress;

         memset(&buffer, 0, BUFFER_SIZE);

         bytes = recvfrom(theSocket, buffer, BUFFER_SIZE, 0,
                   reinterpret_cast<struct sockaddr *>(&clientAddress), &len);
         if (bytes > 0) {
             buffer[bytes-1] = 0;
             cout << "Got \"" << buffer << "\" from "
                  << clientAddress.sun_path << endl;

             // so I can read from what I just got in a formatted way
             stringstream s(buffer);

             int number;
             if (s >> number) {
                 int value = rand() % number+1;

                 // create a result to send back
                 stringstream out;
                 out << "The result of d" << number << " is " << value;

                 // just so I dont' have to do a out.str().c_str()
                 string copy = out.str();

                 memset(&buffer, 0, BUFFER_SIZE);
                 size_t size = min(BUFFER_SIZE, copy.size()+1);
                 strncpy(buffer, copy.c_str(), BUFFER_SIZE-1);
                 bytes= sendto(theSocket, buffer, size, 0, 
                      reinterpret_cast<struct sockaddr *>(&clientAddress), len);
            } else {
                // reset becuase I used it in the previous if.
                s.clear();
                string word;
                s >> word;
                if (word == "quit") {
                    done = true;
                } else {
                // send the message back
                    bytes= sendto(theSocket, buffer, bytes, 0, 
                      reinterpret_cast<struct sockaddr *>(&clientAddress), len);
                }
            }
         }
     }
     close(theSocket);
}