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ąć.