Sockets.

Hi!

Ich wollte mich mal etwas intensiver mit Sockets auseinandersetzen, jedoch hab ich ein Problem.
Ich will mein Programm multi-threaded machen.
Hier erstmal der Code:
Code:
/*
sockets.h
*/
#include <windows.h>
#include <winsock2.h>
class mySock{
      public:
      long result;
      WSADATA wsa;
      SOCKET socketAccept;
      SOCKET socketConnect;
      SOCKADDR_IN addrBind;
      int port;
      
      public:
      mySock(int port);
};
void clientHandler(mySock ms);
void run(mySock ms);



mySock::mySock(int port = 666){
     this->result = WSAStartup(MAKEWORD(2,0), &this->wsa);
     if(this->result != 0){
        printf("WSAStartup() failed.Code: %d GetLastError() returns %d\n",result,GetLastError());
        exit(-1);
     }
     printf("WSAStartup() completed.\n");
     this->port = port;
     
     /*addrBind initialisieren*/
     memset(&this->addrBind,0,sizeof(SOCKADDR_IN));
     this->addrBind.sin_port = htons(this->port);
     this->addrBind.sin_family = AF_INET;
     this->addrBind.sin_addr.s_addr = ADDR_ANY;
     
     /*Bind versuch*/
     this->result = bind(this->socketAccept, (SOCKADDR*) &this->addrBind, sizeof(SOCKADDR_IN));
     if(this->result == SOCKET_ERROR){
        printf("Bind() error! WSAGetLastError() returns %d\n",WSAGetLastError());
        exit(-1);
     }
     printf("bind() completed.\n");
     
     this->socketAccept = socket(AF_INET, SOCK_STREAM, 0);
     this->result = listen(this->socketAccept, 10);
     if(this->result == SOCKET_ERROR){
        printf("listen() error! WSAGetLastError() returns %d\n",WSAGetLastError());
        exit(-1);
     }
     printf("listen() completed.\n");
     CreateThread(0,0, (LPTHREAD_START_ROUTINE) run, (LPVOID) this, 0,0);
     
}


void run(mySock *ms){
   while(true){
      ms->socketConnect = accept(ms->socketAccept, NULL, NULL);
      if(ms->socketConnect==SOCKET_ERROR){
         printf("accept() error! WSAGetLastError() returns %d\n",WSAGetLastError());
         continue;
      }
      CreateThread(0,0, (LPTHREAD_START_ROUTINE) clientHandler, (LPVOID) &ms, 0,0);
   }
}
void clientHandler(mySock *ms){
   char buffer[256];
   recv(ms->socketConnect, buffer, 255, 0);
   printf("Client sendet %s\n",buffer);                       
   send(ms->socketConnect, buffer, sizeof(buffer), 0);
   closesocket(ms->socketConnect);
}
[Linker error] undefined reference to `run(mySock)'
[Linker error] undefined reference to `run(mySock)'
[Linker error] undefined reference to `clientHandler(mySock)'
ld returned 1 exit status

Warum bekomme ich Linker-Errors? clientHandler und run sind doch unten definiert. X(

Das Problem ist schätzungsweise das die Klasse die Funktionen benötigt und umgekehrt.
void run(void * ms) hab ich versucht, aber er meckert wenn ich auf memberobjekte von void zugreifen will. (eg verständlich, aber der Speicher ist doch der gleiche?!?
Muss ich da iwie von void auf mySock convertieren?)
Wie bekomme ich es ans laufen?

Ein paar Tips wären nicht schlecht.


MfG

AlterHacker
 
Hmmm...
Meine Winsock Zeit ist schon ne Weile her, aber was mir so auffällt:
Was ist mySock(int port); für eine Funktion? Kann es sein, dass sie die run und clientHandler Funktion benötigt?
Btw.: An irgendwelchen Typen bzw. Codefehlern wird es nicht liegen. Sonst währe wohl das Kompilieren fehlgeschlagen oder das Programm abgestürzt. Der Linker "verpackt" sozusagen die kompilierten Funktionen in einer Programmdatei. Undefined reference bedeutet also, dass eine Funktion eine Andere aufruft, welche du noch nicht bekannt gemacht hast. (oder die es gar nicht in der Form gibt ^^)
 
Original von Extinction
Hmmm...
Meine Winsock Zeit ist schon ne Weile her, aber was mir so auffällt:
Was ist mySock(int port); für eine Funktion? Kann es sein, dass sie die run und clientHandler Funktion benötigt?
Btw.: An irgendwelchen Typen bzw. Codefehlern wird es nicht liegen. Sonst währe wohl das Kompilieren fehlgeschlagen oder das Programm abgestürzt. Der Linker "verpackt" sozusagen die kompilierten Funktionen in einer Programmdatei. Undefined reference bedeutet also, dass eine Funktion eine Andere aufruft, welche du noch nicht bekannt gemacht hast. (oder die es gar nicht in der Form gibt ^^)
mySock ist der Konstruktor der mySock klasse ;)
Ja sie benötigt run(), welches widerrum clientHandler() benötigt.

Diese werden oben ja "bekanntgemacht" & unten definiert.
 
Ja sie benötigt run(), welches widerrum clientHandler() benötigt.
Diese werden oben ja "bekanntgemacht" & unten definiert.
Sorry, hab mySock mit der main verwechselt. Die steht bei mir immer ganz oben... Btw. eine Main solltest du schon haben. ^^
Versuch einfach mal
void clientHandler(mySock ms);
void run(mySock ms);
vor class mySock zu schreiben. Ich nutze Klassen einfach zu selten...

PS.: Teuflischer Standartport. ;)
 
Original von Extinction
Ja sie benötigt run(), welches widerrum clientHandler() benötigt.
Diese werden oben ja "bekanntgemacht" & unten definiert.
Sorry, hab mySock mit der main verwechselt. Die steht bei mir immer ganz oben... Btw. eine Main solltest du schon haben. ^^
Versuch einfach mal
void clientHandler(mySock ms);
void run(mySock ms);
vor class mySock zu schreiben. Ich nutze Klassen einfach zu selten...

PS.: Teuflischer Standartport. ;)

xD ja dann ist aber mySock undeclared ;)

ne main hat das ding, aber um die geht es ja nicht ;)

Jap, vllt liegts an dem 666 des Default Ports xD
 
xD ja dann ist aber mySock undeclared
Ich seh's auch grade. Heut ist echt nicht mein Tag. >.>

Merkwürdig. Habe ein schematisch gleiches Testprogramm geschrieben (bedingt dadurch, dass es unter Linux kein Winsock gibt):
Code:
int main() 
{
	return 0;	
}

class mySock{
	public:
	int ganzVieleDaten;
	
	public:
	mySock(int port);
};
void clientHandler(mySock *ms);
void run(mySock *ms);

mySock::mySock(int port = 666){
	this->ganzVieleDaten=0;	
	clientHandler(this);
	run(this);
}

void run(mySock *ms)
{
	mySock xy;
	clientHandler(ms);
}

void clientHandler(mySock *ms)
{
	mySock xy;
	run(ms);
}
Gut, so ein Programm macht herzlich wenig Sinn, aber es soll nur demonstrieren, dass die Funktionen einander aufrufen können und mySock's verarbeiten können. Auch mySock(int port) ruft die anderen beiden auf...
Das kompiliert und linkt bei mir einwandfrei. Das die als neue Threads aufgerufen werden, ist afaik nicht wichtig, oder?
Vieleicht liegt es am Linker?

Und kannst du genauere Angaben zu den Linker-Fehlern machen? Eclipse gibt mir eine Meldung wie z.B.
../main.cpp: In constructor ?mySock::mySock(int)?:
../main.cpp:46: Fehler: ?run? wurde in diesem Gültigkeitsbereich nicht definiert
aus. Also mit Zeile, die du am besten im Code markierst, weil die Zeilennummern ja wahrscheinlich unterschiedlich sind.
 
Hier gibst du schon nen Callback mit der falsch definiert ist.
CreateThread(0,0, (LPTHREAD_START_ROUTINE) run, (LPVOID) this, 0,0);

Port 666 solltest du nicht verwenden, weil er noch zu den Wellknown Ports gehört.(0-1023) http://de.wikipedia.org/wiki/Port_(Protokoll)

Ansonsten will ich nicht zuviel ablästern, hab nur kurz drüber geschaut, aber ein paar Dinge fallen sofort als sehr unschön auf.

void run(mySock ms); Hier müsste eigentlich ein Pointer übergeben würden, und dann würde er run vermutlich auch kennen....
 
Original von mauralix
Hier gibst du schon nen Callback mit der falsch definiert ist.
CreateThread(0,0, (LPTHREAD_START_ROUTINE) run, (LPVOID) this, 0,0);

Port 666 solltest du nicht verwenden, weil er noch zu den Wellknown Ports gehört.(0-1023) http://de.wikipedia.org/wiki/Port_(Protokoll)

Ansonsten will ich nicht zuviel ablästern, hab nur kurz drüber geschaut, aber ein paar Dinge fallen sofort als sehr unschön auf.

void run(mySock ms); Hier müsste eigentlich ein Pointer übergeben würden, und dann würde er run vermutlich auch kennen....
DANKE!!!!

Du hast recht.. es fehlte oben ein * xD

"Läster" ruhig viel über mein Programm ab damit ich weiß was ich besser machen kann ;)

EDIT:
Jetzt bekomme ich den Error 10038
//
// MessageId: WSAENOTSOCK
//
// MessageText:
//
// An operation was attempted on something that is not a socket.
//

Wie kann ich den Fehler beheben?
"WSAStartup() completed.
Bind() error! WSAGetLastError() returns 10038 (10038)"


Code:
class mySock{
      public:
      long result;
      WSADATA wsa;
      SOCKET socketAccept;
      SOCKET socketConnect;
      SOCKADDR_IN addrBind;
      int port;
      
      public:
      mySock(int port);
};

[...]

     /*addrBind initialisieren*/
     memset(&this->addrBind,0,sizeof(SOCKADDR_IN));
     this->addrBind.sin_port = htons(this->port);
     this->addrBind.sin_family = AF_INET;
     this->addrBind.sin_addr.s_addr = ADDR_ANY;

     /*Bind versuch*/
     this->result = bind(this->socketAccept, (SOCKADDR*) &this->addrBind, sizeof(SOCKADDR_IN));
     if(this->result == SOCKET_ERROR){
        printf("Bind() error! WSAGetLastError() returns %d (%d)\n",WSAGetLastError(), GetLastError());
        exit(-1);
     }
     printf("bind() completed.\n");
 
Zurück
Oben