Sockets: Server.exe stürzt einfach ab.
-
hi leute,
habe einen Server Programmiert, doch der stürzt einfach hier.
nachdem "Server Gebunden an Port 12345 kommt.Dann kommt keine Rückmeldung mehr.
{ PAINTSTRUCT ps; HDC hdc; static SOCKET s; static SOCKET connectedSocket; long rc; SOCKADDR_IN addr; switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 10, 10, _T("STATUS:"), 7); /////START WINSOCK rc=startWinsock(); if(rc!=0) { TextOut(hdc, 10, 30, _T("Fehler: startWinsock"), 20); return 1;} else { TextOut(hdc, 10, 30, _T("Winsock gestartet!"), 18);} ///// Serversocket erstellen s=socket(AF_INET,SOCK_STREAM,0); if(s==INVALID_SOCKET) { TextOut(hdc, 10, 50, _T("ServerSocket nicht erstellt!"), 28); return 1;} else { TextOut(hdc, 10, 50, _T("ServerSocket erstellt!"), 22);} /////Server Binden memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(12345); addr.sin_addr.s_addr=ADDR_ANY; rc=bind(s,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN)); if(rc==SOCKET_ERROR) { TextOut(hdc, 10, 70, _T("Server Binden gescheitert!"), 26); return 1;} else { TextOut(hdc, 10, 70, _T("Server Gebunden an Port 12345!"),30);} /////Server listen rc=listen(s,10); if(rc==SOCKET_ERROR) { TextOut(hdc, 10, 90, _T("Listen Fehler!"), 15); return 1;} else { TextOut(hdc, 10, 90, _T("Server ist im listenmodus....."),30);} /////Eingehende Verbindungen Akzeptieren connectedSocket=accept(s,NULL,NULL); if(connectedSocket==INVALID_SOCKET) { TextOut(hdc, 10, 140, _T("accept Fehler!"), 14); return 1;} else { TextOut(hdc, 10, 140, _T("Neue Verbindung Akzeptiert!"),27);} EndPaint(hWnd, &ps); break; ...............Was ist der Fehler?
-
listen blockiert.
-
und warum?
-
Warum was?
-
wenn ich listen weglasse, stürzt das programm auch ab.
weiss nich was ich machen soll. so stehts im tutorial von cworker
-
metapoint2011 schrieb:
warum listen blockiert?
Weil es darauf wartet, daß sich ein Client connectet.
-
metapoint2011 schrieb:
warum listen blockiert? und wie mach ich das es funktioniert?
Der Server dann im listen modus befindet. (wartet bis ein Cient sich "verbindet")
Was ist mit den Client ???Gruss Sheldor
-
Naja, listen blockiert nicht, aber accept blockiert. Und das ist so weil es so implementiert ist und so in der Doku steht.
Entweder lässt Du das Socket blockierend und lagerst das ganze auf einen eigenen Thread aus oder Du versetzt das Socket in den Non- Blocking Mode und programierst damit auf dem einen Thread.
-
wie gehts das mit dem non blocking mode?
-
metapoint2011 schrieb:
Was ist der Fehler?
Dass du das in der Behandlung von WM_PAINT machst? Was soll das?
-
MFK schrieb:
metapoint2011 schrieb:
Was ist der Fehler?
Dass du das in der Behandlung von WM_PAINT machst? Was soll das?
naja wegen textout.
hab mal versucht das in wm_command zu machen und alles über ein edit fenster auszugeben, doch dann stürzt das programm sofort ab.
wo mach ich das eigentlich am besten?
-
metapoint2011 schrieb:
wo mach ich das eigentlich am besten?
Außerhalb des GUI-Threads.
-
MFK schrieb:
metapoint2011 schrieb:
wo mach ich das eigentlich am besten?
Außerhalb des GUI-Threads.
und wie geht das?
-
theta schrieb:
Entweder lässt Du das Socket blockierend und lagerst das ganze auf einen eigenen Thread aus oder Du versetzt das Socket in den Non- Blocking Mode und programierst damit auf dem einen Thread.
Gruss Sheldor
-
wie mach ich das auf einen anderen thread?
kann mir einer ein kurzes beispiel geben?
-
Du erzeugst einen Thread mit CreateThread(...),
und rufst dort deine Server Routinen auf.
Während diese dort im Listen mode sind kann dein GUI Thread die Messages des windows handhaben,...greatz
-
okay ich habe jetzt neu angefangen und mal einen Client erstellt.
Problem: Am Ende müsste eine MessageBox kommen die anzeigt ob man Verbunden ist
oder nicht. Die kommt aber nicht.#include "winsock2.h" ..... #pragma comment(lib, "Ws2_32.lib") int startWinsock(void); ..... BOOL CALLBACK ClientSock(HWND, UINT, WPARAM, LPARAM); ..... LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } BOOL CALLBACK ClientSock(HWND hWnd, UINT message, LPARAM lParam, WPARAM wParam) { SOCKET s; long rc; SOCKADDR_IN addr; switch (message) { case WM_COMMAND: /////START WINSOCK rc=startWinsock(); if(rc!=0) { MessageBox(hWnd, _T("Fehler: startWinsock"), _T("Fehler!"), MB_OK); return 1;} /////Clientsocket erstellen s=socket(AF_INET, SOCK_STREAM, 0); if(s==INVALID_SOCKET) { MessageBox(hWnd, _T("ClientSocket nicht erstellt!"), _T("Fehler!"), MB_OK); return 1;} /////Verbinden memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=AF_INET; addr.sin_port=htons(12345); // wir verwenden mal port 12345 addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if(rc==SOCKET_ERROR) { MessageBox(hWnd, _T("Verbinden gescheitert!"), _T("Fehler!"), MB_OK); return 1;} else { MessageBox(hWnd, _T("Verbunden!"), _T("Status"), MB_OK);} break; } return 0; } int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }
-
Ich habs mal auf diese Art hier gelöst.
Ist aber nur nen ungefähres Beispiel, wie du es in die Threads einbauen solltest.
Mußt wahrscheinlich noch ein wenig rumknobeln, damit es bei dir zum Laufen kommt.
Das Problem war immer, wenn ich es in WinMain unterbrachte, dann wurde die MessageBearbeitung blockiert, und das Fenster blieb hängen.
(So wie bei dir auch)
Also lagerte ich das Listen zunächst in einen eigenen Thread aus.
Dort wird dann auf ein Connect gewartet, die Hauptanwendung kann aber weiterhin ihre Messages abarbeiten.
Kommt ein Connect zustande, dann startet der ListenThread einen ConnectThread, der die Kommunikation zwischen Server/Client durchführt.
Ist alles vollbracht, und der Client loggt sich aus, dann wird auch der Connect Thread beendet und der ListenThread kann wieder gestartet werden.
Denkbar ist hier auch, dass der Listen Thread MultiSocket-fähig gemacht wird, so daß er mehrere ConnectThread starten kann.
Aber das müßtest du dir selbst austüfteln. (Dafür muss dem ConnectThread der Socket übergeben werden)Die grundlegende Technik ist diese:
WinMain startet Listen Thread.
WinMain arbeitet weiterhin Messages ab. (Kann auch welche vom ListenThread empfangen oder auch späer vom ConnectThread)
ListenThread wartet auf Verbindungen.
Verbindung trifft ein, es wird ein ConnectThread gestartet.
ListenThread kann weitere ConnectThreads starten wenn weitere Verbindugen angefragt werden.
ConnectThread bearbeitet den Datenaustauch Server/Client.
ConnectThread wird nach Abschluß beendet.So im Groben.
DWORD WINAPI Listen(LPVOID); DWORD WINAPI Connect(LPVOID); WinMain() { In WinMain rufst du dann CreateThread(NULL,0,Listen,(LPVOID)0,0,0); auf. } // Habe mal deinen ListenCode hier eingestellt, weiß nit, ob der auch wirklich läuft. DWORD WINAPI Listen(LPVOID) { SOCKET s; long rc; SOCKADDR_IN addr; /////START WINSOCK rc=startWinsock(); if(rc!=0) { MessageBox(hWnd, _T("Fehler: startWinsock"), _T("Fehler!"), MB_OK); return 1;} /////Clientsocket erstellen s=socket(AF_INET, SOCK_STREAM, 0); if(s==INVALID_SOCKET) { MessageBox(hWnd, _T("ClientSocket nicht erstellt!"), _T("Fehler!"), MB_OK); return 1;} /////Verbinden memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=AF_INET; addr.sin_port=htons(12345); // wir verwenden mal port 12345 addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if(rc==SOCKET_ERROR) { MessageBox(hWnd, _T("Verbinden gescheitert!"), _T("Fehler!"), MB_OK); return 1;} else { MessageBox(hWnd, _T("Verbunden!"), _T("Status"), MB_OK); CreateThread(NULL, 0, Connect, (LPVOID)0, 0, 0);} } DWORD WINAPI Connect(LPVOID) { Hier die Server/Client Kommunikation, Datentransfer usw. unterbringen, ebenso, das Beenden der Verbindung und Aufräumen. }Wie gesagt, mußt da noch ein wenig rumbasteln.
Gruß,
DC
-
alles kla. versuch ich morgen
-
was muss ich denn hinschreiben stadt hWnd? z.b bei ner message box?