Archiv verlassen und diese Seite im Standarddesign anzeigen : RAW Socket - Windows XP SP2
Messiah_of_Death
02.11.2006, 10:10
Guten Morgen :)
hab da ein leichtes seichtes Problem ...
Ich brauch RAW Sockets unter Windows, weil das recv() kein automatisches ACK schickt und mir dadurch die Verbindung zum Endgerät verloren geht.
In der Firma ist es mir nicht aufgefallen, da ich dort mit WinXP SP1 entwickel.
Daheim ( WinXP SP2 ) geht das ganze Programm nicht mehr.
Auf der Microsoft Seite ( Link (http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx) ) steht:
Ab SP2 kein send() über RAW Sockets mehr möglich.
Jetzt mal die Frage an die Spezies hier ( da ich scheinbar die falschen Wörter in Google benutze ):
a. Wie bekomm ich die RAW Sockets unter SP2 wieder zum Senden ?
b. Wie bekomm ich das ACK gesendet OHNE RAW Sockets ? Damit würde sich Frage a erledigen
Danke schonmal für die Antworten..
Gruß
P.S.: WinPCAP wäre eine Möglichkeit, aber bevor ich alles neu mache, wollte ich nach einer "1st-Party"-Möglichkeit fragen
Felix Kaiser
02.11.2006, 10:31
Natürlich sendet der TCP Stack ACKs. Sonst würde die Übertragung ja gar nicht funktionieren. Mindestens alle Daten, die durch recv() an die Anwendung übergeben wurden, sind dann schon durch ein ACK bestätigt.
Es muss auch nicht jedes einzelne Segment mit einem ACK bestätigt werden. Das wäre bei großen Datenmengen auch viel zu uneffektiv. Solange kein PSH gesetzt ist reicht es einige Segmente zu empfangen und dann einfach die letzte Sequenznummer zu bestätigen. Das ist auch erforderlich, damit der Peer weiß, dass und wieviel wieder Platz im Empfangsfenster ist.
Guten Morgen :)
hab da ein leichtes seichtes Problem ...
Ich brauch RAW Sockets unter Windows, weil das recv() kein automatisches ACK schickt und mir dadurch die Verbindung zum Endgerät verloren geht.
In der Firma ist es mir nicht aufgefallen, da ich dort mit WinXP SP1 entwickel.
Daheim ( WinXP SP2 ) geht das ganze Programm nicht mehr.
Auf der Microsoft Seite ( Link (http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx) ) steht:
Ab SP2 kein send() über RAW Sockets mehr möglich.
Jetzt mal die Frage an die Spezies hier ( da ich scheinbar die falschen Wörter in Google benutze ):
a. Wie bekomm ich die RAW Sockets unter SP2 wieder zum Senden ?
b. Wie bekomm ich das ACK gesendet OHNE RAW Sockets ? Damit würde sich Frage a erledigen
Danke schonmal für die Antworten..
Gruß
Das ist richtig, um (böse) Programme auszuschließen, die die Protokolle selber implementieren und sich an den Sicherheitssystemen von Windows vorbeimogeln, sind RAW-Sockets nicht mehr möglich...
Um unter SP2 solche Protokolle oder Sockets zu programmieren, ist mehr Aufwand nötig, entweder man installiert oder bastelt sich einen Protokoll-Layer (im Windows-Jargon: "Filter-Treiber" genannt), oder versucht, das Protokoll über die TAP-Ebene abzufangen.
Ansonsten kannst du dich über die NDIS-Treiber in den Netzwerkstack einhängen!
Aber für die Kontrolle von TCP und UDP stellen die Windowssockets schon selber ein paar Funktionen bereit.
Du möchtest ja einfach, daß eine TCP-Verbindung offen bleibt. Kein Problem, die Windowssockets unterstützen das. Und zwar gehört dieses Verhalten zu den Socketoptionen, und die werden über setsockopt eingestellt: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/setsockopt_2.asp
Die für dich interessante Option ist wohl SO_KEEPALIVE unter den SOL_SOCKET-Optionen. Sollte so funktionieren:
bool keepalive = true;
setsockopt( mysocket, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(bool) );
Danach ist der Socket so umgestellt, daß er automatisch keepalives sendet und die Verbindung offenhält.
Natürlich sendet der TCP Stack ACKs. Sonst würde die Übertragung ja gar nicht funktionieren. Mindestens alle Daten, die durch recv() an die Anwendung übergeben wurden, sind dann schon durch ein ACK bestätigt.
Es muss auch nicht jedes einzelne Segment mit einem ACK bestätigt werden. Das wäre bei großen Datenmengen auch viel zu uneffektiv. Solange kein PSH gesetzt ist reicht es einige Segmente zu empfangen und dann einfach die letzte Sequenznummer zu bestätigen. Das ist auch erforderlich, damit der Peer weiß, dass und wieviel wieder Platz im Empfangsfenster ist.
Defaultmäßig ist es aber nicht so, daß Keepalives gesendet werden müssen. Per default läßt der Stack nämlich zu lange offene Sockets einfach "timeouten"...
Für keepalives (regelmäßig ACKs senden), muß die entsprechende Socket-option eingeschaltet werden.
Messiah_of_Death
02.11.2006, 12:00
Hallo,
ich glaub ich muss doch etwas ausführlicher werden
KEEPALIVE hab ich schon aktiviert. Nützt aber nichts.
Das Endgerät ist ein Industriegerät das auf einem Industrieprotokoll ( ModBus/TCP ) auflegt.
Ich monitore per Wireshark den Verkehr, damit ich sehe ob meine Protokollimplementation korrekt arbeitet. Tut sie auch, WENN ich keine Pause mache. Ich muss aber per Vorgabe zwischen einem Query (an das Gerät ) und einem Response ( von dem Gerät ) 1 sekunde Pause einlegen.
Problem an der Sache ist, dass mein recv() einfach kein ACK sendet. Das Gerät macht nach ~200 ms einfach zu wenn kein ACK kommt bzw macht so oft Re-Transmit bis es bei mir knallt.
Der Verkehr sieht ungefähr so aus
CONNECT - Phase
PC -> query
GERÄT -> ACK
GERÄT -> response
RC -> query
GERÄT -> ACK
GERÄT -> response
Wenn ich keine Pause mache und permament Queries sende bleibt die Verbindung auf.. aber das is nicht Sinn der Sache
meine Receive Methode sieht wie folgt aus
int CSocket::receivedata( unsigned char* cData, int mLen )
{
char *cBuf = new char [ mLen ];
memset( cBuf, 0, mLen);
int v = 0;
int bytes = 0;
SYSTEMTIME _time_start, _time_current;
GetSystemTime( &_time_start );
while ( v < mLen )
{
bytes = recv(this->_socket, &cBuf[v], mLen-v, 0);
if ( bytes <= 0 )
{
return -1;
}
GetSystemTime( &_time_current );
unsigned short milli_curr = _time_current.wMilliseconds;
if ( _time_current.wMinute > _time_start.wMinute )
{
milli_curr += 1000;
}
if ( milli_curr > ( _time_start.wMilliseconds + this->_timeout ) )
{
return -1;
}
v += bytes;
}
memcpy( cData, cBuf, mLen );
return v;
}
meine Send
int CSocket::senddata( const void* cData, int cLen )
{
int bytes_left = cLen;
int bytes = 0;
const char *cbuf = (char*) cData;
int first_byte = 0;
SYSTEMTIME _time_start, _time_current;
GetSystemTime( &_time_start );
while ( bytes_left > 0 )
{
if ( ( bytes = send(this->_socket,
&cbuf[first_byte],
cLen,
0 )) == -1 )
{
return -1;
}
GetSystemTime( &_time_current );
unsigned short milli_curr = _time_current.wMilliseconds;
if ( _time_current.wMinute > _time_start.wMinute )
{
milli_curr += 1000;
}
if ( milli_curr > ( _time_start.wMilliseconds + this->_timeout ) )
{
return -1;
}
bytes_left -= bytes;
first_byte += bytes;
}
return first_byte;
}
Kann sein, dass ich etwas falsch mache. Diverse Testprogramme für das Protokoll senden ein ACK nach jedem Receive, darum versteh ich das Verhalten bei meinem Programm nicht
Hallo,
ich glaub ich muss doch etwas ausführlicher werden
KEEPALIVE hab ich schon aktiviert. Nützt aber nichts.
Das Endgerät ist ein Industriegerät das auf einem Industrieprotokoll ( ModBus/TCP ) auflegt.
Ich monitore per Wireshark den Verkehr, damit ich sehe ob meine Protokollimplementation korrekt arbeitet. Tut sie auch, WENN ich keine Pause mache. Ich muss aber per Vorgabe zwischen einem Query (an das Gerät ) und einem Response ( von dem Gerät ) 1 sekunde Pause einlegen.
Problem an der Sache ist, dass mein recv() einfach kein ACK sendet. Das Gerät macht nach ~200 ms einfach zu wenn kein ACK kommt bzw macht so oft Re-Transmit bis es bei mir knallt.
Der Verkehr sieht ungefähr so aus
CONNECT - Phase
PC -> query
GERÄT -> ACK
GERÄT -> response
RC -> query
GERÄT -> ACK
GERÄT -> response
[schnippel]
Kann sein, dass ich etwas falsch mache. Diverse Testprogramme für das Protokoll senden ein ACK nach jedem Receive, darum versteh ich das Verhalten bei meinem Programm nicht
Das heißt, das ACK, das du senden möchtest, ist gar kein TCP-Acknowledge-Paket, sondern ein eigenes Paket, das der Gegenstelle sagt "Ok, bin noch da, lebe noch!"... Oder verstehe ich dich falsch?
Wenn das so ist, mußt du etwas anders arbeiten.
Die Sockets arbeiten standardmäßig "blocking", d.h. bei einem recv() wird der Programmfluß so lange angehalten, bis ein Paket empfangen wird, oder ein Fehler, z.B. ein Timeout, auftritt.
Du hast nun zwei grundsätzliche Möglichkeiten, das Problem zu lösen. Entweder arbeitest du multi-threaded, d.h. du hast noch einen Thread nebenher laufen, der die ACKs sendet. Oder du verzichtest auf die Nebenläufigkeit, und schaltest die Sockets in den Non-blocking mode. In diesem Fall kehren send() und recv() sofort zurück, aber du bekommst auch nicht sofort den Status der Übertragung. Mit non-blocking sockets kannst du ein ganz anderes Timingverhalten erzeugen und du hast viel mehr Kontrolle über das Zeitverhalten, aber die Programmierung ist ungleich komplizierter, da du auf jeden Fall selber synchronisieren, Pakettests machen und die Pakete evtl. auch selber zusammenstückeln mußt!
Dafür kannst du dann mit den Synchronisationsobjekten von Windows, wie Timer, Events, Semaphoren und WaitForSingleObject (bzw. WaitForMultipleObjects) arbeiten. WaitFor...Object kann auch auf Sockets und Pipes warten!
Das Unterfangen in deinem Fall sähe damit zum Beispiel so aus:
Timer-Objekt anlegen
Socket anlegen
Beide in ein Array packen
Timer starten
recv() aufrufen (non-blocking)
WaitForMultipleObjects()
(das Programm wartet jetzt, bis was passiert)
Entweder läuft das Timerobjekt ab, oder der Socket empfängt Daten
Wenn es der Timer war, ACK senden.
Messiah_of_Death
02.11.2006, 12:33
Das heißt, das ACK, das du senden möchtest, ist gar kein TCP-Acknowledge-Paket, sondern ein eigenes Paket, das der Gegenstelle sagt "Ok, bin noch da, lebe noch!"... Oder verstehe ich dich falsch?
So in etwa, ich kann die Verbindung nur am Leben erhalte, wenn ich auf ein Response sofort nach dem Receive ein ACK sende.
Mein Problem ist das ACK Packet .. ich kenn nur die Methode über RAW Sockets bei C ( bei Java ging das glaub über new Datagram {...} ).
Wenn du mir da etwas auf die Sprünge helfen könntest, wie das auch ohne RAW geht ?!
Wenn ich einfach einen String "ACK" schicke, kommt noch das PUSH Flag mit einem ACK Flag und die Verbindung ist auch tot ...
Du hast nun zwei grundsätzliche Möglichkeiten, das Problem zu lösen. Entweder arbeitest du multi-threaded, d.h. du hast noch einen Thread nebenher laufen, der die ACKs sendet. Oder du verzichtest auf die Nebenläufigkeit, und schaltest die Sockets in den Non-blocking mode. In diesem Fall kehren send() und recv() sofort zurück, aber du bekommst auch nicht sofort den Status der Übertragung. Mit non-blocking sockets kannst du ein ganz anderes Timingverhalten erzeugen und du hast viel mehr Kontrolle über das Zeitverhalten, aber die Programmierung ist ungleich komplizierter, da du auf jeden Fall selber synchronisieren, Pakettests machen und die Pakete evtl. auch selber zusammenstückeln mußt!
Dafür kannst du dann mit den Synchronisationsobjekten von Windows, wie Timer, Events, Semaphoren und WaitForSingleObject (bzw. WaitForMultipleObjects) arbeiten. WaitFor...Object kann auch auf Sockets und Pipes warten!
Das Unterfangen in deinem Fall sähe damit zum Beispiel so aus:
Timer-Objekt anlegen
Socket anlegen
Beide in ein Array packen
Timer starten
recv() aufrufen (non-blocking)
WaitForMultipleObjects()
(das Programm wartet jetzt, bis was passiert)
Entweder läuft das Timerobjekt ab, oder der Socket empfängt Daten
Wenn es der Timer war, ACK senden.
Ich glaub das ist etwas overkill, da die Datenpakete selten die 1-2kByte Grenze überschreiten, aber durchaus eine Überlegung wert :)
Danke für diesen Gedankenanstoß schonmal .
Im Grunde genommen, kann das Gerät "idle" eine Verbindung erhalten, aber wenn kein ACK auf eine Response kommt, ist nach ~200 ms Schluss
Das ist ja interessant!
Hier ist mal genau das Thema, das mich ebenfalls aktuell interessiert - deshalb schließe ich mich gleich mal eben an. Ich könnte zwar auch n neuen Thread eröffnen, aber dann könnte man ja sagen, daß ich erstmal hier nachlesen soll.
Falls es jemanden (z.B. den Ersteller des Threads) stört, daß ich mich hier einfach so eingeklinkt habe, mache ich einen eigenen Thread draus. Außerdem weiß ich nicht, ob's besser nach "Netzwerkprogrammierung" oder zu "Windows API" paßt - ist ja irgendwie beides...
Auch bei mir gehts um Raw Sockets und TCP/IP & Co - also, am besten beschreibe ich mal, was ich machen will-
Leider wird das eine längere Geschichte, aber wenn ich das in Einzelteilen erzähle, muß ich sowieso über kurz oder lang das ganze Ding erläutern, weil mich wieder Leute danach fragen werden, warum ich denn überhaupt so einen haarsträubenden Scheiß machen will... - Deswegen erzähl' ich lieber gleich mal vom ganzen Ausmaß des Elends:
Ziel ist, eine Art "Packet Driver" zu basteln, damit man von DOS aus (also dem "DOS Fenster" aka "DOS Box") Pakete senden und empfangen kann. Wenn man es "direkt" auf Windows aufsetzen wollen würde, müßte man dazu leider für jede Win-Version/-Generation was eigenes schreiben - außerdem ist wohl mehreren (voneinander unabhängigen) Quellen zufolge dieses Unterprogramm, das INT 31h Zugriffe auf einem 16Bit-INT-"Interface" abbildet (glaub 2Fh), also quasi "durchleitet", leider etwas buggy - und der Workaround für den Bug ist fast mehr Aufwand als wenn man selber gleich 'n Netzwerkkartentreiber bauen würde... - Nun, soweit, so uninteressant.
Zwischen-Anmerkung: Wirklich traurig, daß der früher übliche "PC Packet Driver"-Standard (INT 60h - die Älteren werden sich vielleicht erinnern) es nicht in das DOS-Fenster geschafft hat. Auch DOSbox (dieser DOS-Emulator da) stellt den nicht zur Verfügung... Und dabei sind das ja keine hardwarenahen Port-Zugriffe, sondern man müßte eben nur INT 60h-Zugriffe hooken. (Für sowas bräucht *ich* nichmal 'n Protected Mode...)
Ein Kumpel brachte mich neulich auf ne Idee, die, so blöde sie sich vielleicht anhört, doch funktionieren könnte. Und zwar, indem man einfach zur Kommunikation zwischen der DOS- und der Windows-Umgebung das einzige benutzt, das beide noch gemeinsam haben: Nämlich ein File oder für Windows-Benutzer: eine Datei.
Habe dann dazu einen kleinen "Standard" entwickelt, der dann auch noch ein bißchen "Funktionality" beinhaltet, auf die ich nicht weiter eingehen will, der Witz ist im Groben der:
Ein Windows-Programm, mit Zugriff auf die Netzwerkumgebung, legt ein File an - und zwar "shared". Zwei Paket-Ringpuffer sind enthalten, einer für Senden, einer für Empfangen. (Und einiges anderes Zeug, Header und so zwecks Selbsterkennung, Clients an-/abmelden etc) Der DOS-"Client" klatscht nun seine Pakete in den Sendepuffer, der Windows-"Server", nimmt sie und ballert sie ins Netz. Der Windows-"Server" seinerseits horcht am Netz und klatscht alles, was nach IPv4 aussieht (er könnt auch einfach alle Pakete nehmen, aber was will der in DOS schon mit dem Rest...) seinerseits in den Empfangspuffer, von wo der DOS-"Client" es lesen kann.
Die Gefahr des FTR ("Festplatte-Tot-Rödelns") und andere Dinge bestehen nicht, da natürlich das File relativ "klein" gewählt wird, so daß es noch dicke in eventuelle File Caches paßt und somit nicht wirklich Schreib-/Lese-Zugriffe auf die HD erzeugen würde, solange es offen bleibt.
Die DOS-Umgebung (also der spätere "Client") bringt selbstredend schon die gesamte TCP/IP-Funktionality mit, da sie ja davon ausgeht, entweder mit 'nem Modem (PPP macht's selbst) oder mit 'nem laufenden Packet Driver (halt INT 60h bis 80h, mit Ausnahmen...) rechnen zu können/müssen.
Mir wär's dann halt am liebsten, gleich die TCP/IP-Pakete, "as is" in die Puffer zu hauen und sie auch so zu kriegen.
Anmerkung für die, die's interessiert: Eigentlich bin in DOS-Coder. Den Win-Part code ich nur, damit auch Win-User mein Game "Multiplayer" zocken können. (Noch nie erlebt, daß andererseits 'n Win-Coder extra für Typen wie mich irgendwo DOS-Fähigkeit einbauen würde. Hoffe, die Leute wissen das zu würdigen...)
Der Win-Part wird in einer BASIC-Variante (Visual Basic, PowerBASIC oder sowas) gemacht, weil besagter Kumpel sich damit halt etwas auskennt - der macht dann den ganzen "GUI" Krempel an dem Ding, weil den sowas im Gegensatz zu mir interessiert.
Aber es gibt ja dieses lustige Winsock, standardmäßig bei allem Win-Zeugs dabei, das netzfähig ist - braucht man also nix extra zu installieren. Sowas ist prinzipiell schonmal gut, denn ich hasse das, wenn der User sich dann, nur weil er 'n Game zocken will, irgendwo paar DLLs zusammensuchen muß (und man die aus lizenzrechtlichen Gründen nichtmal der Einfachheit halber selber dem Game beilegen kann)... - Zocken darf nicht in Arbeit ausarten. Punkt.
Aber damit auch schon vorbei der Herrlichkeit. Letztens hab ich mich schon ein wenig in diverse Tutorials, Winsock betreffend, eingelesen. Ja, TCP geht. Ja, da gibts direkt Sockets für. Naja. Hat aber alles seine Vor- und Nachteile:
Wenn ich dusslige SOCK_STREAM Sockets benutzen würde, müßte ich nämlich folgendes tun:
Jedes von der "DOS-Umgebung" kommende Paket zu Fuß scannen, ob es ein TCP/IP mit gesetztem SYN und gelöschtem ACK ist (also ein "Öffne Verbindung" Paket) oder evtl auch eins mit gesetztem RST (also "Reset"). Wenn ja, dann einen entsprechenden Socket mit den enthaltenen IPs und Ports öffnen.
Leider kann man da aus Gründen, die da nicht dabeistehen, irgendwie nicht ZWEI, sondern nur EINEN Port für den Socket festlegen, das wohl der Zielport ist - aber: Nicht bei allen Protokollen ist der Source Port "beliebig" - manchmal will man den auch selber festlegen (manchmal sind z.B. Source- und Dest-Port gleich).
Wenns ein normales Datenpaket ist, dann auf diesem Socket senden.
Wenns ein leeres ACK ist, dann mal einfach hoffen, daß Sockets sowas auch senden wollen, sonst einfach nix machen und drauf hoffen, daß der schon selber ACKen wird.
Wenns ein ACK+FIN Paket ist, dann Socket schließen.
Noch schlimmer wirds mit den Paketen "von drüben" - denn: Für die DOS-Umgebung muß ich ja vollständige TCP/IP-Pakete simulieren, also muß ich auch den TCP/IP-Header rekonstruieren. Mal abgesehen davon, daß manche Protokolle (u.a. meins) drauf angewiesen sind, die Pakete als Pakete zu kriegen, will sagen, nicht als Stream. (Oder anders ausgedrückt: Bei nem Stream sieht man nicht mehr, wo das eine Paket aufhört und das andere anfängt.) Also macht sichs nicht grade leicht, daraus Pakete zu rekonstruieren und man kann sich da eher nur auf sein Glück verlassen (nämlich, daß einem der Socket die Daten in "Paket-Einheiten" liefert und nicht gelegentlich mal ein paar gleich "zusammenfaßt".)
Was die Rekonstruktion zusätzlich erschwert ist natürlich, daß ich dann auch selber in Win nochmal den ganzen Sequence-Number / Acknowledgenent-Number Kram nachbilden muß, damit der DOS-Part valide Pakete erhält. (Zwar mit anderen Nummern als denen, die der Winsock benutzt, aber das würde ja keiner merken.)
Oder mit anderen Worten: Daß Winsock einem "die Arbeit abnimmt" sorgt bei mir im Endeffekt dafür, daß ich genau die Arbeit, die er mir abnimmt, in Wahrheit zweimal habe - einmal in DOS und einmal in Windows... Nerv.
Dann las ich nun neulich, daß es ja sowas wie RAW SOCKETs gibt und wollte mich schon freuen - aber bei MS weiß man ja schon, daß man sich nicht zu früh freuen sollte. Und, als hätt ichs mir schon gedacht, mußte ich dann genau das lesen, was ich befürchtet hatte: Nämlich, daß aus Gründen des Schindluders, das man damit betreiben könnte, RAW SOCKETs unter WinXP SP2 nun gar nicht mehr möglich sind und unter NT-Verwandten (also NT und 2000) nur dann, wenn man Admin auf der Kiste ist (und viele Zocker wissen nichtmal, was 'n Admin überhaupt ist - aber mit Win2k rummurksen müssen sie natürlich trotzdem unbedingt...)
RAW SOCKETs scheinen eigentlich genau das zu sein, nach dem ich gesucht habe, aber nun fällt das ja wohl mal wieder aus wegen "is nich".
Ich hatte hier mal einen kleinen - nicht zum Thema gehörenden - Zwischentext, der beschreibt, wie einfach es wäre, RAW SOCKETs zu erlauben und 'n kleinen Check zu machen, der verhindert, daß jemand damit böse Dinge tut...
Auf die Art würde man wenigstens die Leute, die bloß "n bissel Internet" damit (mit RAW SOCKETS) machen wollen, nicht total blockieren.
Aber *ich* bin ja nur n kleiner doofer 16bit-Coder... - wenn man ne Riesen-Softwarebude ist, dann kann man natürlich auch einfach 'ne unintelligente "Geht nich"-Universalsperre einbauen...
Hab den Text aber dann entfernt. Interessiert wohl eh keinen.
Nun zu meinem Anliegen:
Der Vorteil von RAW_SOCKETs speziell für mein Problem ist klar erkennbar und liegt auf der Hand - alles andere würde in unverhältnismäßige Sinnlos-Arbeit ausarten, die man sich eigentlich sparen könnte. Daher würd ich gern sowas nutzen und ich vermute mal, daß die Erklärung, warum und wieso, ja wohl ausreichend ist.
Dann gibts da soweit ich weiß noch einen "Hybriden", der so halb das ist, was ich gerne hätte: Einen "RAW-SOCKET light", (SOCK_IP glaub ich) der den IP-Header selber baut, aber einem selbst überläßt, den Protokoll-Header+Paketinhalt einzubauen - dieser wurde seinerzeit mal benutzt, um selber ICMP senden/empfangen zu können (und würde natürlich auch z.B. für TCP gehen) - weiß nicht, ob auch der bei Win XP SP2 gesperrt ist.
Falls jemandem 'ne andere Möglichkeit einfällt, wie ich doch noch zu irgend etwas in dieser Art komme, kann er ja mal antworten. Bin auf Vorschläge angewiesen.
Messiah_of_Death
04.11.2006, 07:45
Wider erwarten hab ich es doch noch hinbekommen
-> Vor connect() ein bind() ausführen
-> nach recv() ein Sleep von mindestens 50 ms ausführen
-> ACK wird gesendet
Hab allerdings als zusätzliche Sicherheit recv() und send() durch recvfrom() bzw sendto() ersetzt ..
:) Danke nochmal für die Denkanstöße
Felix Kaiser
04.11.2006, 11:09
Leider kann man da aus Gründen, die da nicht dabeistehen, irgendwie nicht ZWEI, sondern nur EINEN Port für den Socket festlegen, das wohl der Zielport ist
Wenn du WinSock meinst, dann bist du da ziemlich fehlinformiert. Man verbindet mit connect() zu einem Socket. Natürlich kann man hier nur einen Port angeben, man verbindet ja nur mit einem Port. Wenn man sich auf einen lokalen Port und/oder IP-Adresse festlegen will, benutzt man bind(). Sonst hätte man spätestens bei UDP arge Probleme, schließlich wird hier nichts miteinander verbunden.
Das ist auch keine Microsoft Erfindung. Die Funktionen und Strukturen entsprechen dem POSIX Standard und die gab es schon in UNIX, da gab es überhaupt noch kein Windows und Microsoft war gerade mal stolz auf sein erstes DOS für den IBM PC.
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.