Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с RecvFrom [D6, Win95/98, WinXP]


Страницы:   1 2

FireMan_Alexey ©   (2004-05-16 11:13:00) 

Ув. Мастера!
У меня проблема с 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;
Я просто не пойму, что я сделал неправильно?


Verg   (2004-05-16 13:36:00) [1]

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

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.


FireMan_Alexey   (2004-05-16 13:33:00) [2]

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


Verg   (2004-05-16 13:30:00) [3]


> [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:29:00) [4]

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


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


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


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

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


FireMan_Alexey   (2004-05-16 13:19:00) [6]

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


FireMan_Alexey   (2004-05-16 13:18:00) [7]

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


Verg   (2004-05-16 13:14:00) [8]


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


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

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


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


FireMan_Alexey   (2004-05-16 13:13:00) [9]

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


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

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


Verg   (2004-05-16 13:08:00) [11]


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


Ну да.


Verg   (2004-05-16 13:05:00) [12]

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


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

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


Verg   (2004-05-16 12:58:00) [14]


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


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


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

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


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

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


FireMan_Alexey   (2004-05-16 12:54:00) [17]

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


Verg   (2004-05-16 12:53:00) [18]

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


> 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:44:00) [19]

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


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


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


В FARе набери
route print


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо