Witam. Pisze program na projekt i mam problem z gniazdami - nie potrafię ich prawidłowo zamknąć. Używam funkcji która zamyka połączenie, ale nie widzę wyraźnej różnicy - i tak serwer się sypie. Podobno biblioteka gniazd nie ma oprogramowanego wyjątku na wypadek przerwania połączenia itp. więc trzeba samemu to wykombinować. Tylko nie wiem jak ;/

Wkleje kod bo ludzie różnie piszą kod(używają innych funkcji), to żeby nie było niedomówień, a i przy okazji może ludzie którzy sami zawsze chcieli napisać czat coś ogarną.


To mój serwer:

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

#include <WinSock2.h>
#include <Windows.h>
#include <iostream>

using namespace std;

SOCKADDR_IN addr;

SOCKET sListen;
SOCKET sConnect;
SOCKET* Connections;

int addrlen = sizeof(addr);
int ConCounter = 0; 

struct Buffer
{
    int ID;
    char Nick[12];
    char Message[256];
};


int ServerThread(int ID)
{
    Buffer sbuffer;  
    char* Recv = new char[256];       
    ZeroMemory(Recv, 256);         

    char* Send = new char[sizeof(Buffer)]; 
    ZeroMemory(Send, sizeof(Buffer));   

    recv(Connections[ID], Recv, 256, NULL);
    memcpy(sbuffer.Nick, Recv, 12);
    cout << "Client " << ID << ": Ustawil nazwe na:" << sbuffer.Nick << endl;

    for(;; Sleep(10))
    {
        if(recv(Connections[ID], Recv, 256, NULL))  
        {
            sbuffer.ID = ID;
            memcpy(sbuffer.Message, Recv, 256); 
            memcpy(Send, &sbuffer, sizeof(Buffer)); 

            cout << "Client " << sbuffer.ID << ": " << sbuffer.Message << endl;

            for(int a = 0; a != ConCounter; a++) 
            {
                if(Connections[a] == Connections[ID])
                {
                }
                else  send(Connections[a], Send, sizeof(Buffer), NULL); 
            }
            ZeroMemory(Recv, 256); //Czyszczenie Pamięci dla wiadomości odebranej
        }
    }

    return 0;
}

int InitWinSock()
{
    int RetVal = 0;
    WSAData wsaData;
    WORD DllVersion = MAKEWORD(2,1);
    RetVal = WSAStartup(DllVersion, &wsaData);
    return RetVal;
}

int main()
{
    int RetVal = 0;
    RetVal = InitWinSock(); 
    if(RetVal != 0)
    {
        MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);
        exit(1);
    } 
    Connections = (SOCKET*)calloc(64, sizeof(SOCKET));
    sListen = socket(AF_INET, SOCK_STREAM, NULL);
    sConnect = socket(AF_INET, SOCK_STREAM, NULL); 
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");   
    addr.sin_port        = htons(1234);             
    addr.sin_family      = AF_INET;                   
    bind(sListen, (SOCKADDR*)&addr, sizeof(addr));
    listen(sListen, 64);

    for(;; Sleep(50))
    {
        if(sConnect = accept(sListen, (SOCKADDR*)&addr, &addrlen)) 
        {
            Connections[ConCounter] = sConnect; 

            char* ID = new char[64]; 
            ZeroMemory(ID, sizeof(ID));

            itoa(ConCounter, ID, 10); 
            send(Connections[ConCounter], ID, sizeof(ID), NULL);

            ConCounter = ConCounter + 1; 
            CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE) ServerThread, (LPVOID)(ConCounter - 1), NULL, NULL);
        }
    }

    return 0;
}

Klient:

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

#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <stdio.h>

using namespace std;

SOCKADDR_IN addr;  
SOCKET sConnect;  

struct Buffer
{
    int ID;
    char Nick[12];
    char Message[256];
};

int ClientThread()
{
    Buffer sbuffer; 
    char buffer[sizeof(sbuffer)] = {0};

    for(;; Sleep(10))
    {
        if(recv(sConnect, buffer, sizeof(sbuffer), NULL))
        {
            memcpy(&sbuffer, buffer, sizeof(sbuffer));
            cout << sbuffer.Nick << ":> " << sbuffer.Message <<endl;
        }
    }

    return 0;
}

int main()
{
    system("cls"); 
    int RetVal = 0;
    WSAData wsaData;
    WORD DllVersion = MAKEWORD(2,1);
    RetVal = WSAStartup(DllVersion, &wsaData);
    if(RetVal != 0)
    {
        MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);
        exit(1);
    }

    sConnect = socket(AF_INET, SOCK_STREAM, NULL);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port        = htons(1234);
    addr.sin_family      = AF_INET;

    cout << "Connect to Masterserver? [ENTER]" <<endl;
    getchar();
    RetVal = connect(sConnect, (SOCKADDR*)&addr, sizeof(addr));

    if(RetVal != 0)
    {
        MessageBoxA(NULL, "Could not connect to server", "Error", MB_OK | MB_ICONERROR);
        main();
    }
    else
    {
        int ID; 
        char* cID = new char[64];
        ZeroMemory(cID, 64);

        recv(sConnect, cID, 64, NULL); 
        ID = atoi(cID); 

        cout << "Connected" <<endl;
        
        cout << "Podaj swoja nazwe(max 12 znakow): ";
        char Nick[12];
        ZeroMemory(Nick, 12);
        cin >> Nick;
        send(sConnect, Nick, 256, NULL);

        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE) ClientThread, NULL, NULL, NULL);

        for(;; Sleep(10))
        {
            char* buffer = new char[256];
            ZeroMemory(buffer, 256);

            cin >> buffer;
            getchar();
            send(sConnect, buffer, 256, NULL);
        }
    }

    return 0;
}


Wiem, że jak bym wystarczająco długo pomęczył tym pytaniem wujka google, to w końcu by się złamał i powiedział jak to zrobić ale mam kilka dni na oddanie wersji alfa i muszę to szybko ogarnąć.