Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.07.11;
Скачать: CL | DM;

Вниз

Проблема с 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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.041 c
3-1087446671
r9000
2004-06-17 08:31
2004.07.11
Определение номера колонки редактируемой таблицы.


1-1088358290
Dio
2004-06-27 21:44
2004.07.11
передача числовых значений из DLL


3-1087278583
Andrey
2004-06-15 09:49
2004.07.11
Программно добавить ODBC DSN


3-1087301567
zevsus
2004-06-15 16:12
2004.07.11
Interbase(Firebird 1.5): Опустошение и репликация


4-1086071681
Чапаев
2004-06-01 10:34
2004.07.11
Named pipes trouble