C++ accept blockiert nicht im Thread

Yogi666

Lt. Junior Grade Pro
Registriert
Mai 2004
Beiträge
329
Hallo.

Wir schreiben zur Zeit ein Spiel welches mit Hilfe von Sockets unter Windows über Netzwerk spielbar sein soll.
Deswegen benutzen wir Threads um den Server und die Clienten abzukapseln.
Allerdings gibt es bei der Auslagerung in den Thread das Problem, dass accept() im Thread nicht mehr blockiert.
Schreiben wir es ohne Threads, blockiert alles ohne Probleme.

So sieht es bisher aus:

#include <iostream.h>
#include "winsock2.h"
#include <ws2tcpip.h>
#include <windows.h>
#include <process.h>

bool goon = true;

void handleclient(void *data) {
SOCKET socket = (SOCKET) data;
char buf[256]; // Buffer für empfangene Daten

// Daten empfangen(blockiert)
recv(socket, buf, 255, 0);

// Verbindung schliesen
closesocket(socket);
goon = false;

_endthread();
}

void waitForClient(void *data) {
SOCKET socket = (SOCKET) data;
SOCKET socketConnect;

while (goon) {
socketConnect = accept(socket, NULL, NULL);
if (socketConnect != SOCKET_ERROR) {
printf("cli added");
_beginthread(handleclient, 0, &socketConnect);
}
}

_endthread();
}

int main(int argc, char* args[]) {

int port = 12345;
int result; // Enthält die Rückgabewerte der Funktionen
WSADATA wsa; // Initialisierungs-Daten
SOCKET socketAccept; // Socket, der Verbindungen annimt
SOCKADDR_IN addrBind; // Daten für das Binden an einen Port

// Mit WSAStartup werden die SoSBckets initialisiert
result = WSAStartup(MAKEWORD(2, 0), &wsa);
if (result != 0) {
printf("Fehler bei WSAStartup(): Code %d", result);
return 0;
} else {
printf("WSAStartup() erfolgreich!");
}

// Initialisieren der Struktur SOCKADDR_IN
memset(&addrBind, 0, sizeof(SOCKADDR_IN));
addrBind.sin_port = htons(port);
addrBind.sin_family = AF_INET;
addrBind.sin_addr.s_addr = ADDR_ANY;

// Initialisierung des socketAccept
socketAccept = socket(AF_INET, SOCK_STREAM, 0);

result = bind(socketAccept, (SOCKADDR*) &addrBind, sizeof(SOCKADDR_IN));
if (result == SOCKET_ERROR) {
printf("Fehler in bind(): Code %d", WSAGetLastError());
return 0;
} else {
printf("bind() erfolgreich!");
}

// socketAccept geht in den "listen-mode"
result = listen(socketAccept, 10);
if (result == SOCKET_ERROR) {
printf("Fehler in listen(): Code %d", WSAGetLastError());
return 0;
} else {
printf("listen() erfolgreich!");
}

// Thread erstellen und weitermachen
_beginthread(waitForClient, 0, &socketAccept);

while (goon);

return 0;
}
Würde mich freuen, wenn jemand weiter weiß :)
 
Hi

[mein Beitrag kann entfernt werden]
 
Zuletzt bearbeitet:
Hi,

versuch mal:

Code:
void waitForClient(void *data) {
SOCKET socket = (SOCKET) data;
SOCKET socketConnect;

socketConnect = accept(socket, NULL, NULL);
if (socketConnect != SOCKET_ERROR) {
printf("cli added");

char buf[256]; // Buffer für empfangene Daten

// Daten empfangen(blockiert)
recv(socketConnect, buf, 255, 0);

// Verbindung schliesen
closesocket(socketConnect);
goon = false;

}

_endthread();
}

oder alternativ einfach die while Schleife in waitForClient entfernen.

MFG

Arnd
 
Wäre schön, wenn man den Code auch in einen entsprechenden Bereich packen könnte. Is dann angenehmer zu lesen.

Wenn ich das richtig sehe, wird der Thread mit
Code:
_beginthread(waitForClient, 0, &socketAccept);
gestartet, also die Adresse des Sockets übergeben.
Im Thread wird dann aber mit
Code:
void waitForClient(void *data) {
	SOCKET socket = (SOCKET) data;
die Adresse des Sockets als Socket interpretiert. Müsste vermutlich
Code:
void waitForClient(void *data) {
	SOCKET socket = *(SOCKET*) data;
heißen. Bei der anderen Funktion das gleiche ...

Das is das, was mir jetzt aufgefallen ist. Bin allerdings nicht sicher, was sich hinter "SOCKET" unter Windows verbirgt und habe auch schon seit einiger Zeit nicht mehr mit C++ gearbeitet ;-)

Edit: War wohl etwas zu langsam ...
 
Du übergibst *SOCKET und wandelst diesen dann im thread zu SOCKET
 
Oky Problem behoben^^ danke für die antworten, wir waren zu nachlässig mit dem casten.
 
Zurück
Oben