Jackson Simpson
Jackson Simpson

Reputation: 29

C++ multi threaded server

I'm working on a server that just connects a client and sends back what they type. So far it works well, but I want to make it multi-threaded so I can connect more clients, so they can "Talk." Can you guys refer me to any source code that I can look over to make some adjustments to my own code? Thanks. I would also like this to work on different networks, and I am not sure how to do this so some source code to that as well would work. Also I'm in eighth grade and haven't had a lot of experience so a well-explained answer would be appreciated.

int main() {

    WSADATA wsaData;

    // Initialize Winsock
    int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if(iResult != 0)
    {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    struct addrinfo *result = NULL,
                    hints;

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;      // Internet address family is unspecified so that either an IPv6 or IPv4 address can be returned
    hints.ai_socktype = SOCK_STREAM;    // Requests the socket type to be a stream socket for the TCP protocol
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;

    // Resolve the local address and port to be used by the server
    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if (iResult != 0)
    {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    SOCKET ListenSocket = INVALID_SOCKET;

    // Create a SOCKET for the server to listen for client connections
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);

    if (ListenSocket == INVALID_SOCKET)
    {
        printf("Error at socket(): %d\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }

    // Setup the TCP listening socket
    iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);

    if (iResult == SOCKET_ERROR)
    {
        printf("bind failed: %d", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    freeaddrinfo(result);

    // To listen on a socket
    if ( listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR)
    {
        printf("listen failed: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    SOCKET ClientSocket;

    ClientSocket = INVALID_SOCKET;

    // Accept a client socket
    ClientSocket = accept(ListenSocket, NULL, NULL);

    if (ClientSocket == INVALID_SOCKET)
    {
        printf("accept failed: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    char recvbuf[DEFAULT_BUFFER_LENGTH];
    int iSendResult;

    // reveice until the client shutdown the connection
    do {
        iResult = recv(ClientSocket, recvbuf, DEFAULT_BUFFER_LENGTH, 0);
        if (iResult > 0)
        {
            char msg[DEFAULT_BUFFER_LENGTH];
            memset(&msg, 0, sizeof(msg));
            strncpy(msg, recvbuf, iResult);

            printf("Received: %s\n", msg);

            iSendResult = send(ClientSocket, recvbuf, iResult, 0);

            if (iSendResult == SOCKET_ERROR)
            {
                printf("send failed: %d\n", WSAGetLastError());
                closesocket(ClientSocket);
                WSACleanup();
                return 1;
            }

            printf("Bytes sent: %ld\n", iSendResult);
        }
        else if (iResult == 0)
            printf("Connection closed\n");
        else
        {
            printf("recv failed: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            //return 1;
        }
    } while (iResult > 0);

    // Free the resouces
    closesocket(ListenSocket);
    WSACleanup();

    getchar();
    return 0;
}

Upvotes: 0

Views: 6457

Answers (1)

Smit Ycyken
Smit Ycyken

Reputation: 1209

There are dozens of ways how to implement this solution.

First of all, it is better to design what approach is preferable for your educational purposes.

Considering network programming:

One of the best guides for network programming I can recommend is Beej's Guide.

Considering server-side architecture:

I would like to recommend C++ Concurrency in Action: Practical Multithreading by Anthony Williams for further reading.

Before you, a whole sea of possibilities - go for it!

Ps: considering general questions like this

It is better to look for an answer to such questions in softwareengineering forum.

Upvotes: 3

Related Questions