Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];

Вниз

Проблема с RecvFrom   Найти похожие ветки 

 
FireMan_Alexey ©   (2004-05-16 11:13) [0]

Ув. Мастера!
У меня проблема с RecvFrom.
Function TUDP.RecieveFrom;
Var
 Addr:TSockAddr;
 Size:Integer;
Begin
 Size:=SizeOf(Addr);
 {Addr.sin_family:=AF_INET;
 Addr.sin_port:=HtoNS(9000);
 Addr.sin_addr.S_addr:=INADDR_ANY;}
 Result:=RecvFrom(FSocket,Buff,Count,0,Addr,Size);
{Здесь вылетает ошибка 10062-неправильно указанный параметр как я понял}
 If Result=SOCKET_ERROR Then
   Begin
     FError:=WSAGetLastError;
     Exit;
   End;
End;
Я просто не пойму, что я сделал неправильно?


 
FireMan_Alexey ©   (2004-05-16 11:18) [1]

Да и еще создание сервера:
Procedure TUDP.OpenServer;
Begin
 FSocket:=SOCKET(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
 If FSocket=Invalid_Socket Then
   Begin
     FError:=WSAGetLastError;
     Error;
   End;
 FAddr.sin_family:=AF_INET;
 FAddr.sin_port:=HtoNS(Port);
 FAddr.sin_addr.S_addr:=INADDR_ANY;
 FError:=Bind(FSocket,FAddr,SizeOf(FAddr));
 If FError=SOCKET_ERROR Then
   Begin
     FError:=WSAGetLAstError;
     Error;
   End;
 WSAAsyncSelect(FSocket,FHandle,UDP_MESSAGE,FD_READ or FD_WRITE);
End;

И посылка широковещательных датаграмм:
Function  TUDP.SendBroadCast;
Var
 Addr:TSockAddr;
 Bol1:Bool;
Begin
 If Count>512 Then
   Begin
     FError:=-1;
     Result:=-1;
     Exit;
   End;
 Bol1:=True;
 Addr.Sin_Family:=AF_INET;
 Addr.Sin_Port:=HtoNS(Port);
 Addr.Sin_Addr.S_addr:=INADDR_BROADCAST;
 SetSockOpt(FSocket,SOL_SOCKET,SO_BROADCAST,PChar(@Bol1),SizeOf(Bol1));
 Result:=SendTo(FSocket,Buff,Count,0,Addr,SizeOf(Addr));
 If Result=SOCKET_ERROR Then
   Begin
     FError:=WSAGetLastError;
   End;
End;


 
Verg ©   (2004-05-16 11:37) [2]


> Function TUDP.RecieveFrom;


Пакажи а как и где ты вызываешь эту ф-цию.
И еще. Ты ничего не путаешь с кодом ошибки: точно WSAELOOP?


 
FireMan_Alexey ©   (2004-05-16 11:47) [3]

Procedure TUDP.WndProc;
Begin
 Case M.Msg of
   WM_QUERYENDSESSION:;
   UDP_MESSAGE:
     Begin
       FError:=WSAGetSelectError(M.LParam);
       If FError<>0 Then
         Begin
           Error;
         End;
       Case WSAGetSelectEvent(M.LParam) Of
         FD_READ:
           If Assigned(FERead) Then
             FERead(Self);
         FD_WRITE:
           If Assigned(FEWrite) Then
             FEWrite(Self);
       End;
     End;
 End;
End;

А в обработчике:

Procedure TMain_.Read;
Var
 S,IP:String;
 Size:Integer;
Begin
//
 Size:=TUDP(Sender).RecieveLength;
 Size:=TUDP(Sender).RecieveFrom(S[1],Size,IP);
 If TUDP(Sender).FError<>0 Then
 Memo1.Lines.Add(IntToStr(TUDP(Sender).FError));
 Memo1.Lines.Add("Read From: "+IP+" "+S);
End;


 
Verg ©   (2004-05-16 11:51) [4]

Да, похоже проблема с тем, что ты используешь сокет с локальным адресом INADDR_ANY для отсылки датаграмм.


 
FireMan_Alexey ©   (2004-05-16 11:54) [5]

Что именно ты имееш ввиду?
У меня при создании сервера адрес INADDR_ANY, а при отсылки
INADDR_BROADCAST.


 
FireMan_Alexey ©   (2004-05-16 11:56) [6]

Если можно, укажи свое мыло и я вышлю весь код программы, так будет легче обсуждать


 
Verg ©   (2004-05-16 12:06) [7]


> [5] FireMan_Alexey ©   (16.05.04 11:54)
> Что именно ты имееш ввиду?
> У меня при создании сервера адрес INADDR_ANY, а при отсылки
> INADDR_BROADCAST.


Да получается, что у датаграммы адрес назначения (DST) =INADDR_BROADCAST, а вот адрес источника(SRC)=INADDR_ANY (т.е. 0). Т.о. recvfrom, которая и вытаскивает тебе SRC из датаграммы вынуждена вернуть некорректный результат в адресе. Вот она и сообщает
10062  = WSAELOOP  Cannot translate name.


 
Verg ©   (2004-05-16 12:08) [8]

Я понял, что FSocket, который в bind. это тот же FSocket, который в SendTo.
Так?


 
Verg ©   (2004-05-16 12:09) [9]


> [6] FireMan_Alexey ©   (16.05.04 11:56)


На http://webfile.ru выложи.


 
FireMan_Alexey ©   (2004-05-16 12:13) [10]

Да ты правильно понял!
webfile.ru/8465


 
FireMan_Alexey ©   (2004-05-16 12:17) [11]

А при создании INADDR_BROADCAST вылетает ошибка 10049 - некоректный адрес!


 
Verg ©   (2004-05-16 12:27) [12]


> [11] FireMan_Alexey ©   (16.05.04 12:17)


В FARе набери
route print


 
FireMan_Alexey ©   (2004-05-16 12:44) [13]

Я все понимаю, но мне нужно слушать все датаграммы посланные на этот порт, я никак не пойму почему у меня это не работает!
INADDR_ANY - 0
INADDR_BROADCAST - FF.FF.FF.FF
Оба присутствуют в списке сетевых адресов


 
Verg ©   (2004-05-16 12:53) [14]

Давай пока по порядку начнем


> Procedure TMain_.Read;
> Var
>  S,IP:String;
>  Size:Integer;
> Begin
> //
>  Size:=TUDP(Sender).RecieveLength;
  setlength(S, Size);
>  Size:=TUDP(Sender).RecieveFrom(S[1],Size,IP);
>  If TUDP(Sender).FError<>0 Then
>  Memo1.Lines.Add(IntToStr(TUDP(Sender).FError));
>  Memo1.Lines.Add("Read From: "+IP+" "+S);
> End;


 
FireMan_Alexey ©   (2004-05-16 12:54) [15]

Согласен пропустил, но это никак не влияет на RecvFrom


 
Verg ©   (2004-05-16 12:57) [16]

Т.е. как бы у тебя д.б. выскакивать WSAEFAULT а не какая другая ошибка...


 
FireMan_Alexey ©   (2004-05-16 12:57) [17]

Спасибо все работает!


 
Verg ©   (2004-05-16 12:58) [18]


> [15] FireMan_Alexey ©   (16.05.04 12:54)


А так, что:
WSAEFAULT The buf or from parameters are not part of the user address space, or the fromlen parameter is too small to accommodate the peer address.


 
FireMan_Alexey ©   (2004-05-16 13:04) [19]

Т.е. Адрес моей строки был nil и поэтому RecvFrom ругался, я правильно понял?


 
Verg ©   (2004-05-16 13:05) [20]

Да и bind на INADDR_ANY. Windows сетевое ядро при sendto на таком сокете тем не менее меняет локальный адрес датаграммы на выбранный по ТМ.
Так что, с [7] - это я перемудрил.
Вот только откуда у тебя бралось WSAELOOP - тогда загадка....


 
Verg ©   (2004-05-16 13:08) [21]


> [19] FireMan_Alexey ©   (16.05.04 13:04)


Ну да.


 
FireMan_Alexey ©   (2004-05-16 13:10) [22]

У меня кроме ошибки 10049 не возникало вообще
а это WSAEINVAL - не правильный параметр, а еще я вот вопрос как получить адрес отправителя, а то у меня 195.225.156.28 постоянно выскакивает?


 
FireMan_Alexey ©   (2004-05-16 13:13) [23]

А мне нужно мой адрес из локалки 192.168.0.101


 
Verg ©   (2004-05-16 13:14) [24]


> {Здесь вылетает ошибка 10062-неправильно указанный параметр
> как я понял}


А это у тебя откуда тогда?

> а еще я вот вопрос как получить адрес отправителя, а то
> у меня 195.225.156.28 постоянно выскакивает?


Все правильно - посмотри свою таблицу маршрутизации - как назначен путь для 255.255.255.255 :))))
Это твой диалапный IP-шник выскаивает.


 
FireMan_Alexey ©   (2004-05-16 13:18) [25]

Получается свой внутренний адрес прийдется зашивать в пакете?
А про 10062 я просто напутал, таблицу с ошибками смотрел и написал не то что нужно!


 
FireMan_Alexey ©   (2004-05-16 13:19) [26]

Так главное и на локальных машинах выходит мой диалапный адрес, как тогда можно определить откуда пришел пакет?


 
Verg ©   (2004-05-16 13:20) [27]


> [25] FireMan_Alexey ©   (16.05.04 13:18)
> Получается свой внутренний адрес прийдется зашивать в пакете?


Не понял - что ты подразумеваешь под "внутренний адрес".

Ты почитай
http://www.zeiss.net.ru/docs/technol/tcpip/tcp12.htm
для начала.


 
FireMan_Alexey ©   (2004-05-16 13:29) [28]

Я имел ввиду, что когда моя машина находится в интернете, то всем машинам в моей сети класса С отсылается айпишник диалапный, а в моей сети адреса 192.168.0.*. А мне нужно определить на другой машине какой Хост отослал пакет и получается, что моя машина отсылает адрес не 192.168.0.101 а IP который мне выдал провайдер! И скажем я захочу приконектиться к серверу который уже создан на ТСР протоколе но на другом порту и укажу инетовский адрес и скажем через пять минут мне прийдется выключить инет, то что тогда произойдет?


 
Verg ©   (2004-05-16 13:30) [29]


> [26] FireMan_Alexey ©   (16.05.04 13:19)


Что делает хост с несколькими сетевыми интерфейсами, когда приложение посылает датаграмму UDP на адрес 255.255.255.255?
Некоторые системы посылают одно широковешь. сообщ. с основного интерфейса с IP-адресом получателя, равным широковещ. адресу подсети этого и-фейса. Другие посылают по одной копии датаграммы с каждого и-фейса, поддерживающего броадкастинг.
Но строго говоря, если приложению нужно грамотно отправить широк. сообщение со всех интерфесов,то оно должно получить конфигурацию и-фейсов и выполнить по одной Sendto для каждого из них, указав в качестве адреса получателя широковещательный адрес подсети этого ифейса (ifaddr or not ifaddr_netmask для IPv4). Вот тогда только будет гарантированно правильная работа так, как тебе надо. А отправка на INADDR_BROADCAST - система распорядится с твоей датаграммой так, как ей нужно, что не всегда совпадает по смыслу с тем, что задумал ты.


 
FireMan_Alexey ©   (2004-05-16 13:33) [30]

Ясно!
ОГРОМНОЕ СПАСИБО за помощь!
Буду думать как это все провернуть.


 
Verg ©   (2004-05-16 13:36) [31]

Я думаю тебе пригодится

unit IPHelper;

interface
uses Windows;
const
 MAX_INTERFACE_NAME_LEN  = 256;
 MAX_TRANSPORT_NAME_LEN  = 40;
 MAX_MEDIA_NAME          = 16;
 MAX_PORT_NAME           = 16;
 MAX_DEVICE_NAME         = 128;
 MAX_PHONE_NUMBER_LEN    = 128;
 MAX_DEVICETYPE_NAME     = 16;
 MAXLEN_IFDESCR          = 256;
 MAXLEN_PHYSADDR         = 8;

type
 TIPAddr = ULONG;     // An IP address.
 TIPMask = ULONG;     // An IP subnet mask.
 TIP_STATUS = ULONG;  // Status code returned from IP APIs.

   TMIB_IFROW = record
           wszName : array[0..MAX_INTERFACE_NAME_LEN-1] of widechar;
           dwIndex,
           dwType,
           dwMtu,
           dwSpeed,
           dwPhysAddrLen : DWORD;
           bPhysAddr : array[0..MAXLEN_PHYSADDR-1] of BYTE;
           dwAdminStatus,
           dwOperStatus,
           dwLastChange,
           dwInOctets,
           dwInUcastPkts,
           dwInNUcastPkts,
           dwInDiscards,
           dwInErrors,
           dwInUnknownProtos,
           dwOutOctets,
           dwOutUcastPkts,
           dwOutNUcastPkts,
           dwOutDiscards,
           dwOutErrors,
           dwOutQLen,
           dwDescrLen : DWORD;
           bDescr : array[0..MAXLEN_IFDESCR-1] of BYTE;
end;

PMIB_IFROW = ^TMIB_IFROW;

const
 MIB_IF_TYPE_OTHER              = 1;
 MIB_IF_TYPE_ETHERNET           = 6;
 MIB_IF_TYPE_TOKENRING          = 9;
 MIB_IF_TYPE_FDDI               = 15;
 MIB_IF_TYPE_PPP                = 23;
 MIB_IF_TYPE_LOOPBACK           = 24;
 MIB_IF_TYPE_SLIP               = 28;

 MIB_IF_ADMIN_STATUS_UP         = 1;
 MIB_IF_ADMIN_STATUS_DOWN       = 2;
 MIB_IF_ADMIN_STATUS_TESTING    = 3;

 MIB_IF_OPER_STATUS_NON_OPERATIONAL =     0;
 MIB_IF_OPER_STATUS_UNREACHABLE     =     1;
 MIB_IF_OPER_STATUS_DISCONNECTED    =     2;
 MIB_IF_OPER_STATUS_CONNECTING      =     3;
 MIB_IF_OPER_STATUS_CONNECTED       =     4;
 MIB_IF_OPER_STATUS_OPERATIONAL     =     5;

type
 
TMIB_IFTABLE = record
   dwNumEntries : DWORD;
   table        : array[0..0] of TMIB_IFROW;
end;
PMIB_IFTABLE = ^TMIB_IFTABLE;

TMIB_IPADDRROW = record
   dwAddr,
   dwIndex,
   dwMask,
   dwBCastAddr,
   dwReasmSize : DWORD;
   unused1,
   unused2 : WORD;
end;
PMIB_IPADDRROW = ^TMIB_IPADDRROW;

TMIB_IPADDRTABLE = record
 dwNumEntries : DWORD;
 table        : array[0..0] of TMIB_IPADDRROW;
end;
PMIB_IPADDRTABLE= ^TMIB_IPADDRTABLE;

TMIB_IPFORWARDROW = record
 dwForwardDest     : DWORD;
 dwForwardMask     : DWORD;
 dwForwardPolicy   : DWORD;
 dwForwardNextHop  : DWORD;
 dwForwardIfIndex  : DWORD;
 dwForwardType     : DWORD;
 dwForwardProto    : DWORD;
 dwForwardAge      : DWORD;
 dwForwardNextHopAS : DWORD;
 dwForwardMetric1   : DWORD;
 dwForwardMetric2   : DWORD;
 dwForwardMetric3   : DWORD;
 dwForwardMetric4   : DWORD;
 dwForwardMetric5   : DWORD;
end;
PMIB_IPFORWARDROW = ^TMIB_IPFORWARDROW;

const
   MIB_IPROUTE_TYPE_OTHER   = 1;
   MIB_IPROUTE_TYPE_INVALID = 2;
   MIB_IPROUTE_TYPE_DIRECT  = 3;
   MIB_IPROUTE_TYPE_INDIRECT= 4;

type
TMIB_IPFORWARDTABLE = record
 dwNumEntries  : DWORD;
 table         : array[0..0] of TMIB_IPFORWARDROW;
end;
PMIB_IPFORWARDTABLE = ^TMIB_IPFORWARDTABLE;

function   GetIfTable(pIfTable : PMIB_IFTABLE; var pdwSize : ULONG; bOrder : BOOL): DWORD; stdcall;

function GetIpAddrTable(pIpAddrTable : PMIB_IPADDRTABLE; var pdwSize : ULONG; bOrder : BOOL): DWORD; stdcall;

function SendARP(DestIP:DWORD;SrcIP:DWORD; var pMacAddr; var PhyAddrLen:DWORD):DWORD;stdcall;

function  SetIfEntry(pIfRow : PMIB_IFROW   // specifies interface and status
): DWORD; stdcall;

function GetIpForwardTable(
 pIpForwardTable : PMIB_IPFORWARDTABLE;  // buffer for routing table
 var pdwSize : ULONG;                       // size of buffer
 bOrder : BOOL                          // sort the table
): DWORD; stdcall;

function GetBestInterface(
 dwDestAddr : DWORD;     // destination IP address
 var pdwBestIfIndex : DWORD // index of interface with the best route
) : DWORD; stdcall;

function GetIfEntry(var pIfRow : TMIB_IFROW ): DWORD; stdcall;  // pointer to interface entry

function NotifyRouteChange(var Handle : THandle; var overlapped : TOverlapped):DWORD; stdcall;

implementation

function   GetIfTable;       external "IPHLPAPI.DLL";
function   GetIpAddrTable;   external "IPHLPAPI.DLL"; // Для твоих целей - эта ф-ция - то, что дохтур прописал
function   SendARP;          external "IPHLPAPI.DLL";
function   SetIfEntry;       external "IPHLPAPI.DLL";
function   GetIpForwardTable;external "IPHLPAPI.DLL";
function   GetBestInterface; external "IPHLPAPI.DLL";
function   GetIfEntry;       external "IPHLPAPI.DLL";
function   NotifyRouteChange;external "IPHLPAPI.DLL";

end.



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.035 c
14-1087991603
Daniel_
2004-06-23 15:53
2004.07.11
Как зарегестрировать шрифт в системе?


3-1087474359
serg128
2004-06-17 16:12
2004.07.11
Как получить сумму поля fld в TClientDataSet?


6-1084461636
Raff
2004-05-13 19:20
2004.07.11
Курс валют


3-1086944771
Manfred8
2004-06-11 13:06
2004.07.11
Вопрос по Sql


14-1088084163
Jonny
2004-06-24 17:36
2004.07.11
Архиватор





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский