Sockets - UDP freien Port/TCP lokalen Port
-
Hi!
Ich muss sagen, ich verstehe die Sockets noch nciht ganz. Ich möchte wissen,
was ich machen muss, das sich UDP einen freiverfügbaren Port aussucht der
noch nicht verwendet wird.Dann wie ich bei bei einem connect zu einem TCP-Server angeben kann, das er
zu Port 80 eine Verbindung aufbauen soll, aber auf dem Clientrechner er den
Port 1001 benutzt.Und noch nebenbei: Es ist doch nicht unbedingt nötig, extra mit Threads zu
arbeiten, wenn ich ich als TCP-Server zwar auf Clients warten, aber nicht
gleich das Programm unterbrechen möchte. Wie mache ich das?mfg olli
-
Vertex schrieb:
Dann wie ich bei bei einem connect zu einem TCP-Server angeben kann, das er
zu Port 80 eine Verbindung aufbauen soll, aber auf dem Clientrechner er den
Port 1001 benutzt.Wende vor dem connect() einfach auf das SOCKET ein bind()
Vertex schrieb:
Und noch nebenbei: Es ist doch nicht unbedingt nötig, extra mit Threads zu
arbeiten, wenn ich ich als TCP-Server zwar auf Clients warten, aber nicht
gleich das Programm unterbrechen möchte. Wie mache ich das?mfg olli
Guck dir mal select() oder WSAAsyncSelect() an...
-
Danke ersteinmal für die Antwort. Mit dem bind() habe ich jetzt schon verstanden, aber MSDN liefert nicht gerade verständliche
Informationen für WSAAsyncSelect(). Könntest Du es kurz erklähren? Es braucht doch hoffentlich
keine CallBack-Funktion ?oder
mfg olli
-
Warst du hier?!
Wenn ich das richtig sehe bekommst du dann eben Nachrichten über die MessageProc des angegebenen Fensters
-
Habe mir mal nen Bsp Server angeschaut mit WSAAsyncSelect(), und das ganze
läuft dann so ab, das an die angegebene hWnd eine Nachricht gesendet wird,
die einem mitteilt, dass ein Client verbunden ist. Ich bräuchte aber nur
ne Accept-Funktion, die mir mitteilt, ob ein Client da ist, oder nicht.
Also ohne Winmessage, CallBack oder Programmstop.
mfg olli
-
Du willst also eigentlich nicht benachrichtigt werden, sondern selber abfragen, ob ein User da ist
-
Evtl. funktioniert das:
Den Socket für den du listen() aufrufst vorher auf non-blocking setzen
(z.B. mit ioctlsocket() und FIONBIO) dann müsste accept() mit INVALID_SOCKET (und GetLastError() wird WSAEWOULDBLOCK liefern) zurückkehren wenn kein Verbindungsaufbau anliegt und ansonsten sollte es dann eben den Socket zurückliefern
-
Heisst es eigentlich "Das Socket" ? "Die Socket" oder "Der Socket" ?
-
flenders: genau
geeky: danke, das war genau was ich gesucht habe, leider muss ich dann weiter
unten lesen:Requirements
Client: Requires Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.
Server: Requires Windows Server 2003, Windows 2000 Server, or Windows NT Server.
Header: Declared in Winsock2.h.
Library: Use Ws2_32.lib.eine funktion für win95, naja sagen wir mindestens win98 würde das ganze noch
perfekt machen.
mfg olli
-
Gibt es überhaupt andere Server-Versionen von Windows ?!
Windows 98 ist kein Server-Windows
-
oO ich brauch doch kein Windowsserver um einen TCP-Server auf zu machen?
-
lol. ioctlsocket läuft unter Windows 95. Guck bei den Client-Anforderungen.
Das mit dem Client/Server heißt in der Doku heißt was anderes. Was weiß ich auch nicht.
-
Hallo,
asdfasdf schrieb:
Das mit dem Client/Server heißt in der Doku heißt was anderes. Was weiß ich auch nicht.
diese Aufteilung zeigt einfach nur, auf welchen Client- oder auf welchen Server-Betriebssystemen die API-Funktion überhaupt implementiert ist. Um Server-Systeme "schlanker" zu halten, werden diese einfach um ein paar Funktionen "erleichtert".
MfG
-
Hi!
Danke, danke, danke!
Gut dann kann ich doch ioctlsocket() benutzen.
Und mal kurz zum Ablauf wie ich das für ein Server dann anstellen müsste:
- WSACleanup
- WSAStartup
- socket
- bind
- ioctlsocket
- listen
und dann kann ich in einer schleife immer
- accepSocket = accept
- if(accpetSocket!=SOCKET_ERROR) -> neuer client
dürfte doch so funzen ?oderAch und eh ich es vergesse, kann ich noch igrendwo ein Timeout angeben, also das er max. für ein Accept 5 Sekunden,
oder max. 2 Sekunden zum lesen von Daten verwenden darf.mfg olli
-
Wenn die sockets in den non-blocking mode gebracht hast wird accept() quasi sofort nen Socket liefern (oder eben INVALID_SOCKET) - Auf jedenfall keine 5 Sekunden
Wenn du die Sockets die accept() liefert, auch non-blocking machst, verhält sich recv() genauso. Wenn gerade keine Daten da empfangen werden wird recv() SOCKET_ERROR zurückliefern und WSAGetLastError() wird als Begründung WSAEWOULDBLOCK liefern (The socket is marked as nonblocking and the receive operation would block.)
Wenn du also maximal 2 Sekunden lang lesen willst:DWORD timeEnd; char buffer[5000]; int bytesReceived; int bytePos; timeEnd=GetTickCount()+2000; bytePos=0; while (GetTickCount()<=timeEnd) // Solange keine 2000 ms rum sind { bytesReceived=recv(einSocket,(buffer+bytePos),50,0); // Maximal 50 Bytes auf einmal einlesen if (bytesReceived!=SOCKET_ERROR) { // Es wurden nen paar Bytes empfangen: bytePos=bytePos+bytesReceived; } else { if (WSAGetLastError()!=WSAEWOULDBLOCK)) { // Es ist irgendein Fehler aufgetreten // WSAWOULDBLOCK käme wen nur keine Daten zum abholen // bereit wären, es ist aber nen anderer Fehler aufgetreten OutputDebugString("Ein böser Fehler ist aufgetreten! \n"); } } }
...ist natürlich nur Pseudo-Code - Man müsste z.B. eigentlich noch prüfen ob man nicht über den Speicherbereich vom buffer hinausschreibt
Wenn Du durch die timeouts nur erreichen willst dass deine Programm-Oberfläche nicht einfriert während auf Daten gewartet wird oder Daten eingelesen werden solltest du dir aber besser Threads angucken!