3 Pluspunkte 0 Minuspunkte

Wie kann ich diesen Code umschreiben so das sich mehrere Benutzer gleichzeitig verbinden können und für jeden Benutzer ein eigener Thread erstellt wird der die anderen nicht blockiert?

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

void client_handler(SOCKET clientSocket) {

    send(clientSocket, "Hello from server!", sizeof("Hello from server!"), 0);
    
    closesocket(clientSocket);

}

int main() {

    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(12345);
    serverAddr.sin_addr.s_addr = INADDR_ANY;

    bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));

    listen(serverSocket, 5);

    while(1) {

        // Jede neue verbindung als Thread an client_handler übergeben

    }

    closesocket(serverSocket);

    WSACleanup();

    return 0;

}

von  

2 Antworten

1 Pluspunkt 0 Minuspunkte

Hier ist ein Beispiel mit pthreads.

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

#include <pthread.h> // Fügen Sie die pthread-Bibliothek hinzu

void *client_handler(void *arg) {
    
    int clientSocket = *((int *)arg);

    send(clientSocket, "Hello from server!", sizeof("Hello from server!"), 0);
    
    closesocket(clientSocket);
    
    return NULL;
    
}


int main() {

    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(12345);
    serverAddr.sin_addr.s_addr = INADDR_ANY;

    bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));

    listen(serverSocket, 5);

    while (1) {
    
        SOCKET clientSocket;
        struct sockaddr_in clientAddr;
        int clientAddrLen = sizeof(clientAddr);

        clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrLen);

        // Starte einen neuen Thread für jeden Client
        pthread_t thread;

        if (pthread_create(&thread, NULL, client_handler, &clientSocket) != 0) 
            return 1;

        // Der Hauptthread sollte sich nicht um diesen Client kümmern, daher setzen wir ihn in den Hintergrund
        pthread_detach(thread);
        
    }

    closesocket(serverSocket);

    WSACleanup();

    return 0;

}
von (776 Punkte)  
1 Pluspunkt 0 Minuspunkte

Zuerst bindest du die Windows API ein.

#include <windows.h>

Die client_handler Funktion schreibst du so um.

DWORD WINAPI client_handler(LPVOID lpParam) {

    SOCKET clientSocket = (SOCKET)lpParam;

    send(clientSocket, "Hello from server!", sizeof("Hello from server!"), 0);
    
    closesocket(clientSocket);
    
    return NULL;
    
}

Und im Mainloop ersetzt du die Schleife folgendermaßen.

while (1) {
    SOCKET clientSocket;
    struct sockaddr_in clientAddr;
    int clientAddrLen = sizeof(clientAddr);

    clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrLen);

    // Starten Sie einen neuen Thread für diesen Client
    DWORD threadId;
    HANDLE threadHandle = CreateThread(NULL, 0, client_handler, (LPVOID)clientSocket, 0, &threadId);

    if (threadHandle == NULL) {
        perror("CreateThread");
        return 1; // Fehler beim Erstellen des Threads
    }

    // Schließen Sie den Thread-Handle, da wir es nicht mehr benötigen (der Thread läuft jetzt selbstständig)
    CloseHandle(threadHandle);
}

von (542 Punkte)