Komisches Problem mit nem Socket
-
Hi, ich habe ein ganz komisches Problem wie ich finde.
hier erstmal code..void *WarteAufGameServer(void *name) { CMySocket *pSocket; pSocket = new CMySocket(false); char buffer[200]; int rc; int neuer_socket; struct sockaddr_in remoteaddr; socklen_t len=sizeof(remoteaddr); //pSocket->Port = 200; pSocket->CreateServer(false,1700); printf("1\n"); //neuer_socket = accept(pSocket->ServerSocket,NULL,NULL); printf("1,5\n"); while(1) { printf("2\n"); //rc = pSocket->SocketRecv(buffer,200,neuer_socket); rc = recvfrom(pSocket->ServerSocket,buffer,200,0,(struct sockaddr*)&remoteaddr,&len); printf("%s\n",buffer); } } //////////////////////Main Funktion//////////////////////// int main() { CMainServer *MainServer; CMySocket *pMySocket; MainServer = new CMainServer; pMySocket = new CMySocket(true); pthread_t WarteAufServer; pthread_create(&WarteAufServer,NULL,WarteAufGameServer,(void *)"hallo"); int clients[50]; fd_set fdSet; int b; int rc; char *RecvBuffer; MainServer->LadeUser(); //pMySocket->Port = 1600; pMySocket->CreateServer(true,1600); for(b=0;b<=50;b++) { clients[b]=0; } while(1) { FD_ZERO(&fdSet); FD_SET(pMySocket->ServerSocket,&fdSet); for(b=0;b<=50;b++) { if(clients[b]!=0) { FD_SET(clients[b],&fdSet); } } select(51,&fdSet,NULL,NULL,NULL); if(FD_ISSET(pMySocket->ServerSocket,&fdSet)) { for(b=0;b<=50;b++) { if(clients[b]==0) { clients[b]=accept(pMySocket->ServerSocket,NULL,NULL); printf("Neuer Client verbunden\n"); break; } } } for(b=0;b<=50;b++) { if(clients[b]==0) { continue; } if(FD_ISSET(clients[b],&fdSet)) { RecvBuffer = new char[1024]; rc = pMySocket->SocketRecv(RecvBuffer,500,clients[b]); //printf("%s\n",RecvBuffer); if(rc<=0) { printf("Client %d hat die Verbindung beendet\n",clients[b]); close(clients[b]); FD_CLR(pMySocket->ServerSocket,&fdSet); clients[b] = 0; delete [] RecvBuffer; } else { if(MainServer->CheckUser(RecvBuffer)==1) { pMySocket->SocketSend(clients[b],"1",2); } else { pMySocket->SocketSend(clients[b],"0",2); } } } } } return 0; }
die Dateien main.h und mysocket.h sind denke mal unwichtig.
Also das Problem. Ich erstelle ja einmal in der Main Funktion einen TCP Socket, daher beim initialisieren "true". Setze ihn auf Port 1600.
so der socket läuft einwandfrei, er nimmt verbindungen an usw...
so nun in der Funktion "WarteAufGameServer" erstelle ich ja auch einen Socket. in diesem falle einen UDP.. möchte aber auch TCP is mir eigentlich egal.. naja jedenfall erstelle ich in der Funktion noch eine Instanz der CMySocket Klasse. Nur leider wird kein Port dafür geöffnet. Sprich kein Client kann sich verbinden. Egal ob mit TCP oder UDP...Ich hoffe ich könnt mir helfen.
-
Wenn das wirklich passiert, dann müstest du ja auch einen Fehler zurück gegeben bekommen. Wo tritt der denn auf. Bei welcher Funktion?
-
aso das habe ich vielleicht vergessen zu erwähnen..
also wenn ich nen TCP Socket erstelle:
Ich habe in der Datei MySocket.cpp in der Methode "CreateServer(bool TCP, int Port)" von der Klasse "CMySocket" eine kleine Überprüfung eingebaut.
Man benötigt ja eine bind und listen Funktion um einen TCP Socket zu erstellen.also habe ich überprüft:
int rc; rc = bind(....); if(rc==0) { printf("bind erfogreich\n"); } else { printf("bind nicht erfolgreich\n"); } rc = listen(...); if(rc==0) { pritnf("listen erfolgreich\n"); } else { printf("listen nich erfolgreich\n"); }
diese beiden funktionen geben jeweils 0 zurück, sprich der socket wird gebunden und auf listen gesetzt. Soweit ok. Jetzt kommt die Funktion accept
int client_socket; client_socket = accept(server_socket,NULL,NULL);
server_socket ist natürlich auch nen int und wir bei bind und listen mitverwendet.
aber bei der accept funktion bleibt er hängen.
Habe mal nen Printf("hallo\n"); dahiter geschrieben, leider wurde dieses nich ausgeben.Jetzt zum UDP Socket.
dort braucht man ja nur die bind funktion und danach kommt das recvfrom bind wird ebenfalls erfolgreich ausgeführt und dann friert der thread ebenfalls ein.ich hoffe das erklärt es jetzt etwas besser...
-
Irgendwas mit Feier-Woahl?
-
nene... keine Firewall und auch keine ipchanges festgelegt.. alles offen.
In der MainFunktion baut der ja einwandfrei nen ServerSocket auf nur im Thread nicht... *heul*weiß denn sonst keiner Rat?
-
server_socket ist natürlich auch nen int und wir bei bind und listen mitverwendet.
aber bei der accept funktion bleibt er hängen.
Habe mal nen Printf("hallo\n"); dahiter geschrieben, leider wurde dieses nich ausgeben.Natuerlich nicht, schlisslich blockiert und zwar so lange, bis ein Client sich
verbindet -> man accept.dort braucht man ja nur die bind funktion und danach kommt das recvfrom bind wird ebenfalls erfolgreich ausgeführt und dann friert der thread ebenfalls ein.
Auch recvfrom blockiert, wenn keine Daten anstehen. Evtl. sind keine Daten zum
empfangen da?mfg
v R
-
ja das ist schon klar das der blockiert, nur trotzdem müsste ja ein Port geöffnet werden, so das sich ein Client verbinden kann. Nur wenn kein port offen ist, kann sich auch niemand verbinden...
-
Wie sieht denn CreateServer aus? Koenntest du mal den Code posten, wo die
Socket-Struktur angelegt und der Socket erstellt wird?mfg
v R
-
kein Thema:
hier die mysocket.cpp und die mysocket.h und die main.h//Main.h // Main Gameserver Klasse class CMainServer { public: CMainServer(); ~CMainServer(); void LadeConfig(); void LadeUser(); int CheckUser(char *user); private: char ConfigPath[50]; char UserPath[50]; char *User[50]; };
//MySocket.h #include <cstdlib> #include <stdio.h> #include <unistd.h> #include <syslog.h> #include <sys/types.h> #include <netinet/in.h> #include <string.h> #include <sys/socket.h> #include <sys/select.h> class CMySocket { public: CMySocket(bool TCP); int CreateServer(bool TCP,int Port); void SocketSend(int Socket,char *buffer,int len); int SocketRecv(char *buffer,int len,int Socket); int Port; int ServerSocket; int ClientSocket; struct sockaddr_in addr; socklen_t addr_len; };
//MySocket.cpp #include "MySocket.h" CMySocket::CMySocket(bool TCP) { if(TCP==true) { ServerSocket = socket(AF_INET,SOCK_STREAM,0); } else { ServerSocket = socket(AF_INET,SOCK_DGRAM,0); } } int CMySocket::CreateServer(bool TCP,int Port) { int rc; addr.sin_family = AF_INET; addr.sin_port = htons(Port); addr.sin_addr.s_addr=INADDR_ANY; addr_len = sizeof(addr); rc = bind(ServerSocket,(struct sockaddr*)&addr,sizeof(addr)); if(rc==0) { printf("Erfolgreich gebunden\n"); } else { printf("Nicht erfolgreich gebunden\n"); } if(TCP==true) { rc = listen(ServerSocket,3); if(rc==0) { printf("Server listen....\n"); } else { printf("Fehler beim listen\n"); } } return 1; } int CMySocket::SocketRecv(char *buf,int len,int socket) { int rc; rc = recv(socket,buf,len,0); return rc; } void CMySocket::SocketSend(int socket,char *buffer,int len) { send(socket,buffer,len,0); }
bitteschön, jetzt sind alle 4 dateien online
-
weiß denn KEINER Rat?? Ich habe keine Ahnung warum.. hier sind doch soviele Profis,
-
Also ich fasse jetzt erst einmal zusammen. Ich kann nämlich so auf anhieb in deinem Code keinen Fehler finden. Also. Dein Programm läuft ohne Fehler durch und dann bleibt es stehen aber kein port ist offen. Versuch jetzt erste einmal dein Programm auf TCP zu stellen und benutze dann den befehl
netstat -a
um zu gucken, ob doch kein Port geöffnet wurde.
-
Hab was gefunden:
Ich benutze
socket(PF_INET, SOCK_STREAM, 0);
im gegensatz zu dir.
-
ich kienn jetzt leidfer nich den Unterschied zwischen AF_INET und PF_INET aber daran liegt es hoffe ich mal nich, muss gleich mal nachlesen.
das andere SOCK_STREAM ist ja für TCP Verbiundungen und SOCK_DGRAM ist für UDP Verbindungen. Eigentlich sollte das ja so korrekt sein.
oder was meinst du??
Nochmal zu deiner Zusammenfassung:
In der Mainfunktion wird ein Port geöffnet und Clients können sich verbinden.In der WarteAufServer Funktion SOLLTE ein Port geöffnet werden. Tut es aber NICHT weder auf UDP noch auf TCP Basis!!
-
snoopdog schrieb:
das andere SOCK_STREAM ist ja für TCP Verbiundungen und SOCK_DGRAM ist für UDP Verbindungen. Eigentlich sollte das ja so korrekt sein.
Eigentlich schon, nur hab ich mich mit UDP noch nicht beschäftigt. Soweit ich mir den TCP teil angeschaut habe sollte der aber ansonsten OK sein.
-
ja dasist ja das Problem an der Sache. Für mich ist der Code auch korrekt nur leider funktioniert es ja nicht.. was mich sehr sehr wundert...
Ob ich nun TCP als Verbindungsart oder UDP nutze ist mir eigneltich schnuppe, jedenfalls in dem Fall.
-
Der Port den du öffnest wird als "mps-raft" in netstat angezeigt!!!
Ich hab alles mal ein bisschen umgeschrieben, bis ich darauf gekommen bin. Ich hab dann den port geändert.
#include <cstdlib> #include <stdio.h> #include <unistd.h> #include <syslog.h> #include <sys/types.h> #include <netinet/in.h> #include <string.h> #include <sys/socket.h> #include <sys/select.h> #include <pthread.h> #define DPORT 4325 class CMySocket { public: CMySocket(bool TCP); int CreateServer(bool TCP,int Port); int ServerSocket; struct sockaddr_in addr; socklen_t addr_len; }; CMySocket::CMySocket(bool TCP) { if(TCP==true) { ServerSocket = socket(PF_INET,SOCK_STREAM,0); printf("TCP Socket created!\n" ); } else { ServerSocket = socket(PF_INET,SOCK_DGRAM,0); printf("UDP Socket created!\n" ); } } int CMySocket::CreateServer(bool TCP,int Port) { int rc; addr.sin_family = AF_INET; addr.sin_port = htons( Port ); addr.sin_addr.s_addr=INADDR_ANY; addr_len = sizeof(addr); rc = bind(ServerSocket,(struct sockaddr*)&addr,sizeof(addr)); if(rc==0) { printf("Erfolgreich gebunden\n"); } else { printf("Nicht erfolgreich gebunden\n"); } if(TCP==true) { rc = listen(ServerSocket,1); if(rc!=0) { perror("Fehler beim listen\n"); } else { printf("Server listen....\n"); } } return 1; } //Main.h // Main Gameserver Klasse void *WarteAufGameServer(void *name) { CMySocket *pSocket; pSocket = new CMySocket(true); char buffer[200]; int rc; int neuer_socket; struct sockaddr_in remoteaddr; socklen_t len=sizeof(remoteaddr); pSocket->CreateServer(true, DPORT); printf("1\n"); struct sockaddr_in accept_addr; int accept_addr_len = sizeof( accept_addr ); neuer_socket = accept(pSocket->ServerSocket, (struct sockaddr*)&accept_addr, (socklen_t*)&accept_addr_len); printf("Connetion\n"); printf("1,5\n"); //while(1) { printf("2\n"); //rc = pSocket->SocketRecv(buffer,200,neuer_socket); rc = recvfrom(pSocket->ServerSocket,buffer,200,0,(struct sockaddr*)&remoteaddr,&len); printf("%s\n",buffer); } } int main() { pthread_t WarteAufServer; pthread_create(&WarteAufServer,NULL,WarteAufGameServer,(void *)"hallo"); while(1); return 0; }
-
öhm werde ich morgen inner mittagspause mal testen, bin jetzt zu müde...
Soweit ich das auf dem ersten Blick erkenne hast du parameter 2 und 3 von der funktion accept besetzt. Hm kann es daran liegen? in meiner MainFunktion habe ich Parameter 2 und 3 ja auch auf NULL stehen.
was mir noch aufgefallen ist, warum hast du die while(1) in der WarteAufGameServer auskommentiert? Somit wird ja nur einmal recvfrom aufgerufen und sobald der einmal eine Nachricht bekommt wurd der Thread beendet. er sollte jedoch pausenlos im Hintergrund mitlaufen und áuf Nachrichten warten.
Aber danke schonmal
-
Das while hatte ich nur zum Testen auskommentiert. Ich glaube aber, dass dein code schon die ganze Zeit funktioniert hat, nur du hast das nicht bemerkt, weil der Port 1700 schon von für ein bestimmtes Protokoll vorgesehen war(s.o.), welches in netstat angezeigt wurde, statt port 1700.
-
hm. aber am port kann es eigentlich nich gelegen habe, habe auch schon andere ports ausprobiert.. 200 und 1601.. .und bei beiden ging es nicht.. naja werd ich nacher mal testten.
-
ok habs getestet und klappt, sogar mit port 1600. irgendwie komisch das der nich bei nmap angezeigt wird...
wenn ich in der commandline netstat eingebe zeigt der mir ja sämtlcihe offen ports an, aber weder port 1600(TCP) noch 1600(UDP) wie kommt das ?
welchen parameter hast du netstat mitgegeben ??