Hallo zusammen!
Ich habe folgendes Problem: Am PC läuft ein kleines Programm, das an eine bekannte
IP ein UDP-Packet sendet. Der Empfänger antwortet darauf und im Prinzip wars das auch schon. Das ganze funktioniert in der Regel auch problemlos mit einer Ausnahme:
Wenn der Empfänger noch nicht im ARP-Cache steht (oder ich arp -d mache) kann ich im WireShark sehen, das der Stack offenbar zuerst ein "Who has .." absendet und als Antwort auch die korrekte MAC zurückbekommt. Erst danach sendet er mein UDP-Packet und auch die Antwort der Gegenstelle kommt sofort wird aber
nicht zugestellt?!?
Bei mir kommt es dann über einen Timer zu einem Timout (>5Sek) und dadurch wird der Socket geschlossen. Das ist seltsamerweise auch der Moment, in dem ich die Benachrichtigung über die Antwort bekomme (da ist es aber schon zu spät)!
Ich verwende dazu WinSock Aufrufe und die Initialisierung sieht (auszugsweise) so aus:
Delphi-Quellcode:
fSocket := Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
If fSocket <> INVALID_SOCKET
then
begin
iAddrLen := SizeOf(iSockAddr);
iSockAddr.sin_family := AF_INET;
iSockAddr.sin_port := htons(0);
// Port = 0 -> Windwos will select one to receive on!
iSockAddr.sin_addr.S_addr := inet_addr(PAnsiChar(AIP));
// IP of selected interface
If Bind(fSocket, iSockAddr, iAddrLen) <> SOCKET_ERROR
Then
begin
if WSAAsyncSelect(fSocket, fOwner.fWndHdl, WM_DETECTMSG+Cardinal(fIndex), FD_READ) <> SOCKET_ERROR
then
begin
// ok ...
fError := 0;
end
else
begin
CloseSocket(fSocket);
fSocket := INVALID_SOCKET;
fError := WSAGetLastError;
end;
end
Die Antworten werden per Windows-Message empfangen was im Prinzip wie folgt aussieht:
Delphi-Quellcode:
procedure TMyReceicer.HandleMessages(var Message: TMessage);
begin
if (Message.Msg >= WM_DETECTMSG) And (Message.Msg < WM_DETECTMSG+Cardinal(fList.Count)) then
begin
iIndex := Message.Msg - WM_DETECTMSG;
//
//
//
aSocket := Message.WParam;
aFD := Message.LParam And $FFFF; // aError = (lParam Shr 16) And $FFFF);
if aFD = FD_READ then
Begin
iAddrLen := SizeOf(iSocketAddr);
recvBytes:=recvfrom(aSocket, iBuf, Length(iBuf), 0, iSocketAddr, iAddrLen);
if (recvBytes <> SOCKET_ERROR) And (recvBytes >= 256) then
begin
// daten auswerten
end;
end
end;
end;
Ich habe mir über WSAAsyncSelect auch bereits alle möglichen anderen Botschaften zustellen lassen, aber in diesem speziellen Fall ist es einfach so, dass überhaupt nichts in HandleMessage ankommt...
Die Frage ist nun natürlich ob das einfach so hinzunehmen ist, oder ich bei der Initialisierung oder sonst irgendwie erreichen kann, das die Antwort - die ja gesendet und auch empfangen wurde - meiner Funktion zugestellt wird, ohne das ich dazu den Socket schließen muss?
TIA