![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с RecvFrom [D6, Win95/98, WinXP]
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