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

Вниз

Не могу передать данные посредством idUDPClient/idUDPServer   Найти похожие ветки 

 
Nike   (2005-10-16 09:03) [0]

Здравствуйте! Пишу чат для локальной сети. Использую Indy-йские UDP-клиент и Udp-сервер. При отправке широковещательного сообщения возникает следующая проблема: если я отправляю данные методом idUdpClient.Send(Adata:string), то мне удается получить эту строку сервером в событии idUDPServer.onUDPRead, т.е. с доставкой строк проблем не возникает.
Но если я отправляю данные (к примеру, типа byte) методом idUdpClient.SendBuffer(var ABuffer, const ABytesCount: integer), то при получении сервером данных (событие onUDPRead) я получаю "неверные" данные в потоке AData: Stream.
Привожу код для "неверного" случая:


... var F: byte;
...

//Отправка данных
procedure TMainFrm.Button1Click(Sender: TObject);
var buf: TMemoryStream;
   s: string;
begin
buf:=Tmemorystream.Create;
F:=6;
Buf.WriteBuffer(F,1);
Buf.Position:=0;
IdUdpClient1.SendBuffer(Buf,Buf.size);
s:=IdUdpClient1.ReceiveString;
If s="" then ShowMessage("No answer")
else ShowMessage(s);

Buf.Free;
end;

//Прием сообщения
procedure TMainFrm.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;  ABinding: TIdSocketHandle);
var
 buf: TMemoryStream;
 z: byte;
 s: string;
begin
 Buf:=TMemoryStream.Create;
 Buf.CopyFrom(Adata,Adata.Size);
 Buf.Seek(0,0);
 Buf.Read(z,1);

 If z=6 then ShowMessage("Ok12");
 s:="I got";
 With Abinding do
  SendTo(PeerIP,PeerPort,s[1],Length(s));
 Buf.Free;

end;


Может кто-нибудь мне объяснит в чем проблема?


 
Nike   (2005-10-18 09:03) [1]

Конечно, можно и в строку записать данные любого типа, но тогда придется сначала конвертировать данные в строку при отправке, отправлять методом Send(полученная строка), и производить обратную конвертацию (из строки в свой тип данных) при приеме. Мне такой подход как-то не по душе :).
Все же почему не работает метод SendBuffer? У меня руки кривые или это глюк INDY?


 
kami ©   (2005-10-18 14:41) [2]

Сейчас не стоит Indy, но попробую... Если в Индях в SendBuffer используется тоже нетипизированный буфер, то нужно :
IdUdpClient1.SendBuffer(Buf.Memory,Buf.size);
И необязательно тогда устанавливать Position в 0


 
Чапаев ©   (2005-10-18 15:21) [3]


> IdUdpClient1.SendBuffer(Buf,Buf.size);

Эхехе... А ты подумал, ЧТО ты таким образом отправляешь?


 
Чапаев ©   (2005-10-18 15:22) [4]


> У меня руки кривые или это глюк INDY?

Это не глюк Indy, а вот руки... Скорее не кривые, а неопытные. ;-)


 
megabyte-ceercop ©   (2005-12-21 13:51) [5]

Так что же Nike таким образом отправляет?


 
Digitman ©   (2005-12-22 11:12) [6]


> что же Nike таким образом отправляет?


он отправляет buf.size байт начиная с адреса переменной buf, в которой хранятся не данные, которыми управляет объект TMemoryStream и которые собственно и нужно передать, а адрес местонахождения в памяти этого объекта

IdUdpClient1.SendBuffer(Buf.Memory^,Buf.size);


 
Slym ©   (2005-12-22 12:15) [7]

var F:Byte;
begin
F:=6;
IdUdpClient1.SendBuffer(PChar(@F)^,sizeof(f));


 
tesseract ©   (2005-12-23 17:40) [8]


> PChar(@F)^

Зачем ? Можно и просто числа, и стуктуру, и статический массив передавать как нетипизированную переменную. С динамическими массивами сложнее.


 
Eraser ©   (2005-12-23 18:03) [9]


> Nike   (16.10.05 09:03)

При всём том, что тут уже сказали учти, что размер передаваемых данных не должен превышать максимального размера дэйтаграммы, иначе не видать тебе удачи.


 
FrykT ©   (2005-12-24 19:57) [10]

Передавайте всегда в виде строки в пакетах с фиксированным буфером. Продумайте протокол передачи, если данных больше, чем размер одного пакета. Возможно, Вам захочется сделать не на Инди, а на API.
Вот пример UDP сервера на АПИ:
перед закрытием сокета делайте WSAASynchSelect с последним параметром 0.
Событие сокета к окну привязывается с помощью сообщения, например
const WM_NETMESSAGE = WM_USER + 32;
ловится созданием процедуры типа procedure ProcNetMes(var m: TMessage); message WM_NETMESSAGE;
там тип сообщения извлекается из m.lParamLo , ошибка из m.lParamHi, сам сокет - m.wParam
function StartUDPSocket(h:hWnd; var S: Tsocket; var A: TSockAddr;
 Port: Integer): boolean;
begin
 Result := FALSE;
 S := socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
 if S = INVALID_SOCKET then
   exit;
 A.sin_family := AF_INET;
 A.sin_port := htons(Port);
 A.sin_addr.S_addr := htonl(INADDR_ANY);
 FillChar(A.sin_zero, sizeof(A.sin_zero), 0);
 if bind(S, A, sizeof(A)) = SOCKET_ERROR then
 begin
   closesocket(S);
   exit;
 end;
 if listen(S, SOMAXCONN) = SOCKET_ERROR then
 begin
   closesocket(S);
   exit;
 end;
 WSAAsyncSelect(S, h, WMNETMESSAGE, FD_READ);
 Result := true;
end;


 
FrykT ©   (2005-12-24 19:59) [11]

Сорьки за ошибки, на быструю руку накатал (=



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

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

Наверх





Память: 0.47 MB
Время: 0.019 c
3-1139929240
Ольга
2006-02-14 18:00
2006.04.09
Построение иерархии зависимостей объектов БД


3-1139599601
Варяг
2006-02-10 22:26
2006.04.09
Проблем подключения VFoxPro через ADO


6-1135728507
0xBAD
2005-12-28 03:08
2006.04.09
TWebBrowser и буфер обмена


2-1143213046
Spellcaster
2006-03-24 18:10
2006.04.09
Перебрать в цикле свойства класса


15-1142984761
Andy BitOff
2006-03-22 02:46
2006.04.09
Windows XP Service Pack 2





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