رسالة WSAETIMEDOUT في مكتبة المشبك
سؤال
لماذا أنا دائما الحصول على الخطأ WSAETIMEDOUT في هذا الرمز:
var fUDPBuf: array [1..UdpPacketSize] of byte;
{...}
UDPSocket := TUDPBlockSocket.Create;
UDPSocket.Bind(UDPIP, UDPPort);
if UDPSocket.LastError = 0 then
Raise EDevFail.Create(Format(SPortFailed, [UDPPort]));
while not Terminated do begin
BytesRead := UDPSocket.RecvBufferEx(@fUDPBuf[1], UdpPacketSize, 1000);
if BytesRead <= 0 then
case UDPSocket.LastError of
0, WSAETIMEDOUT: Continue;
WSAECONNRESET, WSAENETRESET,
WSAENOTCONN, WSAECONNABORTED,
WSAENETDOWN: begin
Raise EDevFail.Create(UDPSocket.GetErrorDesc(UDPSocket.LastError));
UDPSocket.CloseSocket;
end;
else begin
Raise EDevFail.Create(UDPSocket.GetErrorDesc(UDPSocket.LastError));
UDPSocket.CloseSocket;
end;
end;
//Sleep(1);
ProcessData(@fUDPBuf[1]);
inc(PacketCount);
end;
وأنا متأكد من أن أتلقى البيانات UDP من جهاز الشبكة الإلكترونية بقدر UdpPacketSize.
المحلول 2
وأنا تحل مشكلتي:)
UDPSocket.Bind(UDPIP, UDPPort);
يجب أن يكون
UDPSocket.Bind('0.0.0.0', UDPPort);
و
if UDPSocket.LastError = 0 then
يجب أن يكون
if UDPSocket.LastError <> 0 then
لللتحقق من عنوان IP حيث تأتي البيانات من
if UDPSocket.GetRemoteSinIP<>UDPIP then ....
نصائح أخرى
في الدعوة "UDPSocket.RecvBufferEx (fUDPBuf [1]، UdpPacketSize، 1000)؛" وأود أن نفترض أن الرقم الأخير هو فترة المهلة. ويتم ذلك بحيث لا يجلس في انتظار إلى الأبد، وإنما يتحقق بشكل دوري إذا تم إنهاء موضوع باستخدام بينما شرط حلقة. لذا المهلة هو الوضع الطبيعي لهذا النوع من التعليمات البرمجية، ويمكن تجاهلها.
ولقد وجدت ذلك. الخطأ هو في
if UDPSocket.LastError = 0 then
وLastError هو 10049 = لا يمكن تعيين العنوان المطلوب في هذه المرحلة. فلماذا لم أتمكن من ربط عنوان UDPIP. لقد تحقق الملكية الفكرية وميناء. هذه هي الصحيحة. وليس هناك غيرها من البرامج الاستماع هذا المنفذ.