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

Вниз

На отправляющий сокет приходит инфа, хотя приходить не должна...   Найти похожие ветки 

 
3APA3A ©   (2004-03-25 22:09) [0]

Объясните мне, пожалуйста, следующее
 создаю сокет
 var sock : Integer;
     lWSA : WSADATA;
     local, remote : sockaddr_in;
     data : Cardinal;
 begin
   WSAStartup(MakeWord(1, 1), lWSA);    
   sock := socket(AF_INET, SOCK_DGRAM, 0);
   local.sin_family := AF_INET;
   local.sin_port := 55000;
   local.sin_addr.s_addr := inet_addr("local ip");
   bind(sock, local, sizeof(local));
   
   remote.sin_family:=AF_INET;
   remote.sin_port:=60000;
   remote.sin_addr.s_addr:=inet_addr("remote ip");  
   
   sendto(sock, data, 4, 0, remote, sizeof(remote));

   n:=sizeof(remote);
   recvfrom(sock, data, 4, 0, remote, n);

   Тестировал в одноранговой локалке. Обнаружил следующее
  1) Если пишу несуществующий  remote-ip, то программа "виснет" на строчке recvfrom, то есть как и положено, так как ничего не приходило
  2) Если пишу существующий remote-ip и порт и на том компьютере создаю сокет с такими свойствами - тоже все в порядке, если с remote comp послал данные - они читаются, не послал - программа ждет...
 3) Если пишу существующий remote-ip  - то
если строчка sendto отсутствует - тоже все нормально, а вот если я сначала туда чего-нибудь пошлю - то recvfrom начинает мне выдавать какие-то данные, причем значение, возвращаемое функцией - что-то порядка 4-8 мегабайт данных... И вот это-то не ясно...
Что мне приходит, и в таких количествах, если тот комп мне ничего не посылал? Причем remote-port не занят никаким приложением, при тестировании я перебрал порядка 50 портов  - везде такая ерунда...
  Объясните мне, или подскажите ,где почитать...


 
Verg ©   (2004-03-25 22:37) [1]

1. Порт в адресе сокета - это 16 битовое без знака (unsigned short), хронящееся в сетевом порядке байт, а мы пока имеем дело только с LITTLE_ENDIAN. Ты же заполняешь это поле в порядке байт хоста. Так что, давай-ка htons(<port>) не забывай. (Host TO Network Short)
2. Я не вижу вообще где ты анализируешь результат recvfrom


 
3APA3A ©   (2004-03-26 08:39) [2]

2. Анализ это что-то типа такого
     i:=recvfrom(sock, data, 4, 0, remote, n);
     ShowMessage(IntToStr(i));
  и  i равно 4-8 мегабайтам... что само по себе странно, ведь я дал запрос на чтение только 4 байт...

1. Сетевой порядок байт - это младший байт по старшему адресу? так?
   Что такое LITTLE_ENDIAN?
   Как я понял из SDK и вашего ответа - htons просто меняет порядок байтов в переменной порта?
   mov ax, port
   xcng ah, al
   mov netport, ax?


 
Verg ©   (2004-03-26 11:23) [3]


> 1. Сетевой порядок байт - это младший байт по старшему адресу?
> так?
>    Что такое LITTLE_ENDIAN?
>    Как я понял из SDK и вашего ответа - htons просто меняет
> порядок байтов в переменной порта?


Именно - remote.sin_port:= htons(60000);


> 2. Анализ это что-то типа такого
>      i:=recvfrom(sock, data, 4, 0, remote, n);
>      ShowMessage(IntToStr(i));
>   и  i равно 4-8 мегабайтам... что само по себе странно,
> ведь я дал запрос на чтение только 4 байт...


Да ну, не межет того быть. Приведи полный код (и без ошибок при копировании paste :) ).


 
3APA3A ©   (2004-03-29 04:18) [4]

Код вот такой

function WaitForData(Sock:Integer;TimeOut:Cardinal):Integer;
var FDS:TFDset;
   Tv:TTimeval;
   Ptv:PTimeVal;
begin
 FD_ZERO(FDS);
 FD_SET(Sock,FDS);
 Ptv:=nil;
 if TimeOut<>INFINITE then
 begin
   Tv.tv_sec:=TimeOut div 1000;
   Tv.tv_usec:=(TimeOut mod 1000) * 1000;
   Ptv:=@Tv;
 end;
 Result:=Select(0,@FDS,nil,nil,Ptv);
end;

procedure a;
begin
 local.sin_family := AF_INET;
 local.sin_port := htons(55000);
 local.sin_addr.S_addr := inet_addr("127.0.0.1");

 remote.sin_family := AF_INET;
 remote.sin_port := htons(55001);
 remote.sin_addr.S_addr := inet_addr("127.0.0.1");

 WSAStartup(MakeWord(1, 1), lWSA);
 s := socket(AF_INET, SOCK_DGRAM, 0);
 bind(s, local, sizeof(local));

 data := 123;

 sendto(s, data, 4, 0, remote, sizeof(local));
 
 n:=WaitForData(s, 1000);
 if n > 0 then ShowMessage("data")
 else
   if n = 0 then ShowMessage("timeout");

объясните пожалуйста, почему этот код выводит мне сообщение "data", ведь ничего не приходило? Если убрать строчку sendto - то все нормально...


 
Polevi ©   (2004-03-29 09:47) [5]

как не приходило ?
sendto(s, data, 4, 0, remote, sizeof(local)); - это что по твоему ?


 
Polevi ©   (2004-03-29 09:49) [6]

гм, сорри, порт другой


 
Polevi ©   (2004-03-29 09:50) [7]

аа, сокет один, создай для сенда другой сокет


 
Verg ©   (2004-03-29 10:16) [8]


> объясните пожалуйста, почему этот код выводит мне сообщение
> "data", ведь ничего не приходило?


Потому, что на сокете s что-то произошло, что требует чтения из него.
Я надеюсь (опять надо именно надеяться), что перемнная n - типа
integer

N := Recv(S,....);
if N= SOCKET_ERROR then
 ShowMessage(SysErrorMessage(WSAGetLastError));


 
Verg ©   (2004-03-29 10:19) [9]

А происходит, скорее всего вот что:

WSAECONNRESET The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket as it is no longer usable. On a UPD-datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.

UPD - это мелкософтовская очепятка :))


 
3APA3A ©   (2004-03-30 11:24) [10]

"аа, сокет один, создай для сенда другой сокет" - блин, я не хочу создавать другой сокет... UDP сокеты работают в дуплексном режиме (или как там это называется) и поэтому мне просто хочется разобраться...

Ясно... то есть, мне приходит просто датаграмма что порт недоступен, то есть система вызывает что-то типа sendto(mysocket, Port_Unreachable)?
 А где прочитать про формат этих служебных датаграмм?
 Или просто recvfrom смотрит что это служебный пакет и выдает мне уже не его, а просто SOCKET_ERROR ?
 Хотелось бы получше разобраться со всем этим...


 
Verg ©   (2004-03-30 11:42) [11]


> Ясно... то есть, мне приходит просто датаграмма что порт
> недоступен, то есть система вызывает что-то типа sendto(mysocket,
> Port_Unreachable)?
>  А где прочитать про формат этих служебных датаграмм?
>  Или просто recvfrom смотрит что это служебный пакет и выдает
> мне уже не его, а просто SOCKET_ERROR ?
>  Хотелось бы получше разобраться со всем этим...


Эти служебные датаграммы - это ICMP (RFC 792).
При отправке UDP датаграммы, сетевое ядро принимающей машинки смотрит, что порт назначения у этой датаграммы никто не обслуживает (нет UDP сокета с таким локальным портом) и ядро отправляет источнику этой UDP датаграммы ICMP пакет - "Порт недоступен". Приняв это ICMP сообщение твое ядро переводит UDP сокет, отправивший ту датаграмму в состояние "готов к чтению, ошибка WSAECONNRESET". Вот и все. recv(from) из этого сокета вернет ошибку SOCKET_ERROR (-1), а WSAGetLastError сообщит, что WSAECONNRESET.

Надо помнить, что этого ICMP сообщения тот, принимающий хост может и не отправить (зависит от реализации) или это сообщение может не придти к тебе по причине файерволов, потерь при передаче и т.п.
Т.е. расчитывать на них не стоит, но и забывать про них тоже нелзя.

Учитесь (не забывайте) анализировать ошибки, возникающие при вызовах ф-ций работы с сокетами и соблюдать типы данных результатов этих ф-ций.


 
3APA3A ©   (2004-03-30 12:07) [12]

Все.. теперь все ясно.. кстати, что такое RFC 792?


 
Verg ©   (2004-03-30 12:18) [13]

http://delphimaster.net/view/6-1080561800/



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

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

Наверх





Память: 0.53 MB
Время: 0.032 c
3-1082623835
Arm79
2004-04-22 12:50
2004.05.16
прокрутка мышью в DBGrid


6-1080487828
iu2320
2004-03-28 19:30
2004.05.16
Shared resources


1-1083676679
oleg_SYS
2004-05-04 17:17
2004.05.16
Сохранение ключа реестра в файл


14-1083148485
Думкин
2004-04-28 14:34
2004.05.16
Погода пииип-пип


14-1082839973
Yegorchic
2004-04-25 00:52
2004.05.16
Отпревка SMS





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский