Форум: "Сети";
Текущий архив: 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 = WSAELOOPCannot 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.055 c