Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Проблема с UDP


Автор: fippo 21.9.2008, 17:57
Пишу программу которая должна подключится к серверу по UDP протоколу, послать запрос, и затем получить ответ. Для этого использую Indy, для отправки udpclient, для получения udpserver. Проблема в том, что сервер ничего не отвечает. Проверял через программу udp telnet, через неё сервер отвечает на команды, а в моей программе нет.
Поискал на эту тему в интернете, нашёл, что клиент при отправке запроса должен указать серверу порт для того, чтоб сервер послал туда ответ (протокол udp). Так вот, в компоненте indy udp server указать клиентский порт нельзя, такой порт выбирается случайным образом. Более того, при открытии этого-же порта с пом. udp server_а, он выдаёт ошибку, что порт уже открыт.
Подскажите пожалуйста, как можно средствами Delphi реализовать передачу и приём данных через udp. Возможно-ли это сделать с пом. Indy, или как-то через сокеты нужно?

Автор: Virtuals 22.9.2008, 11:30
fippo, поуму писать на чистом апи
а проще с использованием
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=657
с исходниками, так что сам со временем напишеш на апи, если захочеш, да и ошибки всегда исправить можно

вот пример начальный с использованием этих компонент
(для контры поиск сервака)
Код

WSocket1.Close;
    WSocket1.Proto      := 'udp';
    WSocket1.Addr       := '255.255.255.255';
    WSocket1.Port       := '27015';
    WSocket1.LocalAddr  := '0.0.0.0';
    WSocket1.LocalPort  := '2715';
    WSocket1.Connect;
    WSocket1.SendStr(#$FF+#$FF+#$FF+#$FF+'TSource Engine Query'+#$00);
//    WSocket1.Close;
//    WSocket1.Listen;

end;

procedure TForm1.WSocket1DataAvailable(Sender: TObject; Error: Word);
var
    Buffer : array [0..1023] of char;
    Len    : Integer;
    Src    : TSockAddrIn;
    SrcLen : Integer;
    sstr:string;
    tmlen:integer;
begin
    SrcLen := SizeOf(Src);
    Len    := WSocket1.ReceiveFrom(@Buffer, SizeOf(Buffer), Src, SrcLen);
    if Len >= 0 then begin
        if (FServerAddr.S_addr = INADDR_ANY) or
           (FServerAddr.S_addr = Src.Sin_addr.S_addr) then begin
            Buffer[Len] := #0;
{
            Memo1.Lines.Add('  ' + StrPas(inet_ntoa(Src.sin_addr)) +
                                          ':'  + IntToStr(ntohs(Src.sin_port)) +
                                          '--> ' + StrPas(Buffer)
            );
}
sstr:='';
for tmlen:=0 to Len-1 do if Buffer[tmlen]<>#0 then sstr:=sstr+Buffer[tmlen];
memo1.Lines.Add('');
memo1.Lines.Add(sstr);
memo1.Lines.Add('');
        end;
    end;
end;


Автор: fippo 22.9.2008, 17:01
Большое спасибо, решил проблему, воспользовавшись компонентами ICS. Действительно, очень удобно smile 

Автор: SneG0K 22.9.2008, 17:02
На сервере и на клиенте порт нужно обязательно указывать!!! Иначе как клиент будет знать, куда отправлять? 

Автор: darkmamba 13.5.2009, 02:36
Помогите отправить по UDP буфер )
Использую стандартный д7 компонент UDPSocket. Проблема в том , что тот буфер который нужно не отправляется. Отправляется стек вместо буфера. Я чето немогу понять как отправлять правильно, сама функция поинтеры не ест, как ей скормить оффсет на буфер.. 

Код

0044E5CA  |.  6A 10         PUSH 10                                  ; /ToLength = 10 (16.)
0044E5CC  |.  8D45 EC       LEA EAX,DWORD PTR SS:[EBP-14]            ; |
0044E5CF  |.  50            PUSH EAX                                 ; |pTo
0044E5D0  |.  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]             ; |
0044E5D3  |.  50            PUSH EAX                                 ; |Flags
0044E5D4  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]             ; |
0044E5D7  |.  50            PUSH EAX                                 ; |DataSize
0044E5D8  |.  56            PUSH ESI                                 ; |Data = 0012F628
0044E5D9  |.  8B43 40       MOV EAX,DWORD PTR DS:[EBX+40]            ; |
0044E5DC  |.  50            PUSH EAX                                 ; |Socket
0044E5DD  |.  E8 42F3FFFF   CALL <JMP.&wsock32.sendto>               ; \sendto


как бы я не ухитрялся чето ниче не выходит, хоть на масме пиши =\

Код ~ такой

Код

a := '12345';
udp.Active := true;
Toaddr.sin_family := AF_INET;
Toaddr.sin_port := htons(27015);
Toaddr.sin_addr.S_addr := inet_addr('212.33.232.147');
udp.SendTo(a,25,Toaddr,0);

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)