I am trying to just make a simple chat program for a server and client to talk to each other with no blocking. I want to be able to send a message at any time and have that pop up on the other's screen when I send it. I am having trouble figuring out how to structure the code to do that (or maybe just using wrong tools). I tried just typical cin and cout, but that blocks. I tried using select(), but I don't think I need that. My latest attempt at it is using the fork process which seems to be the way most threads I have found online do this. However, I am still having trouble doing it. Here is the code

Server -

Code:
//includes taken out

#define PORT "4950"
#define STDIN 0

struct sockaddr name;



void set_nonblock(int socket) {
    int flags;
    flags = fcntl(socket,F_GETFL,0);
    assert(flags != -1);
    fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}


// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
    if (sa->sa_family == AF_INET)
        return &(((struct sockaddr_in*)sa)->sin_addr);

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}


int main(int agrc, char** argv) {
    int status, sock, adrlen, new_sd;

    struct addrinfo hints;
    struct addrinfo *servinfo;  //will point to the results

    //store the connecting address and size
    struct sockaddr_storage their_addr;
    socklen_t their_addr_size;


    //socket infoS
    memset(&hints, 0, sizeof hints); //make sure the struct is empty
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM; //tcp
    hints.ai_flags = AI_PASSIVE;     //use local-host address

    //get server info, put into servinfo
    if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
        exit(1);
    }


    //make socket
    sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
    if (sock < 0) {
        printf("\nserver socket failure %m", errno);
        exit(1);
    }


    //allow reuse of port
    int yes=1;
    if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
        perror("setsockopt");
        exit(1);
    }



    //unlink and bind
    unlink("127.0.0.1");
    if(bind (sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
        printf("\nBind error %m", errno);
        exit(1);
    }

    freeaddrinfo(servinfo);

    //listen
    if(listen(sock, 5) < 0) {
        printf("\nListen error %m", errno);
        exit(1);
    }



    their_addr_size = sizeof(their_addr);
    //accept
    new_sd = accept(sock, (struct sockaddr*)&their_addr, &their_addr_size);
    if( new_sd < 0) {
        printf("\nAccept error %m", errno);
        exit(1);
    }


    cout<<"\nSuccessful Connection!";



    //set nonblock
    set_nonblock(new_sd);


    char* in = new char[255];
    char* out = new char[255];
    int numSent;
    int numRead;
    pid_t pid;


    fork();
    pid = getpid();



    if(pid == 0) {

        while( !(out[0] == 'q' && out[1] == 'u' && out[2] == 'i' && out[3] == 't') ) {

            fgets(out, 255, stdin);
            numSent = send(sock, out, strlen(out), 0);

            if(numSent < 0) {
                printf("\nError sending %m", errno);
                exit(1);
            }   //end error
        }   //end while

    }   //end child


    else {
        numRead = recv(sock, in, 255, 0);
        if(numRead < 0) {
            printf("\nError reading %m", errno);
            exit(1);
        }   //end error
        else {
            cout<<in;
            for(int i=0;i<255;i++)
                in[i] = '\0';

        }   //end else
    }   //end parent



    cout<<"\n\nExiting normally\n";
    return 0;
}


Client -

Code:
//includes taken out

#define PORT "4950"

struct sockaddr name;



void set_nonblock(int socket) {
    int flags;
    flags = fcntl(socket,F_GETFL,0);
    assert(flags != -1);
    fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}


// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
    if (sa->sa_family == AF_INET)
        return &(((struct sockaddr_in*)sa)->sin_addr);

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}


int main(int agrc, char** argv) {
    int status, sock, adrlen;

    struct addrinfo hints;
    struct addrinfo *servinfo;  //will point to the results

    memset(&hints, 0, sizeof hints); //make sure the struct is empty
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM; //tcp
    hints.ai_flags = AI_PASSIVE;     //use local-host address

    //get server info, put into servinfo
    if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
        exit(1);
    }


    //make socket
    sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
    if (sock < 0) {
        printf("\nserver socket failure %m", errno);
        exit(1);
    }



    if(connect(sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
        printf("\nclient connection failure %m", errno);
        exit(1);
    }



    cout<<"\nSuccessful connection!";



    //set nonblock
    set_nonblock(sock);

    char* out = new char[255];
    char* in = new char[255];
    int numRead;
    int numSent;
    pid_t pid;


    fork();
    pid = getpid();


    if(pid == 0) {

        while( !(out[0] == 'q' && out[1] == 'u' && out[2] == 'i' && out[3] == 't') ) {

            fgets(out, 255, stdin);
            numSent = send(sock, out, strlen(out), 0);

            if(numSent < 0) {
                printf("\nError sending %m", errno);
                exit(1);
            }   //end error
        }   //end while
    }   //end child process

    else {

        while( !(in[0] == 'q' && in[1] == 'u' && in[2] == 'i' && in[3] == 't') ) {
        numRead = recv(sock, in, 255, 0);
            cout<<in;
            for(int i=0;i<255;i++)
                in[i] = '\0';
        }
    }   //end parent process


    cout<<"\n\nExiting normally\n";
    return 0;
}
Whenever I run the code, the server side gets an error when trying to read of "Transport endpoint is not connected" and it happens twice (because of fork I'm guessing?).

What am I doing wrong here? I feel like I am using fork wrong, but that might just be because I have never used it before. I'm mainly interested in getting the non-blocking i/o to work properly, but any other things you want to point out are welcomed. Thank you for any help.