Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.224.64.226] |
|
Сообщ.
#1
,
|
|
|
Ребята добрый день!
Я запутался и совсем в отчаянии Раньше я отправлял просто строку по UDP но встала задача именно отправить байты т.е. не печатанные символы и тп для примера я пытаюсь отправить пока что строку из 3х символов как байты: 321 делаю конвертацию по коду ниже и получаю это: https://yadi.sk/i/Dgt1qMYxD0tVYg а в номальной программе которую я скачал там все корректно формируется https://yadi.sk/i/7hrj-rOCIXkQCQ tmp2:="33 32 31"; //ожидается что это 321 g:=0; cnt:=0; while g<=length(tmp2) do begin if pos(' ',tmp2)>0 then begin delete(tmp2,pos(' ',tmp2),1); inc(cnt); end; inc(g); end; inc(cnt); SetLength(buff, cnt); tmp2:=UDP_Server_Client_1.Edit5.Text; g:=0; cnt:=0; while g<=length(tmp2) do begin if pos(' ',tmp2)>0 then begin tmp3:=tmp2; delete(tmp3,pos(' ',tmp3),length(tmp3)); delete(tmp2,1,pos(' ',tmp2)); tmp3:=tmp3; buff[cnt]:=strtoint(tmp3); inc(cnt); end; inc(g); end; tmp2:=tmp2; buff[cnt]:=strtoint(tmp2); inc(cnt); ёUDP_Server_Client_1.IdUDPClient1.SendBuffer(UDP_Server_Client_1.IdUDPClient1.Host,UDP_Server_Client_1.IdUDPClient1.Port,buff); //UDP_Server_Client_1.IdUDPClient1.Send(UDP_Server_Client_1.Edit3.Text); //если нужно отправить просто строку, то отравляем без изменений |
Сообщ.
#2
,
|
|
|
Цитата Emmys @ tmp2:="33 32 31"; //ожидается что это 321 кем ожидается? var Buf: TIdBytes; Begin SetLength(Buf, 3); Buf[0] := $33; Buf[1] := $32; Buf[2] := $31; IdUDPClient1.Send(Buf); End; Добавлено Ещё так попробуй: IdUDPClient1.Send(#$33#$32#$31, Indy8BitEncoding); |
Сообщ.
#3
,
|
|
|
Цитата Emmys @ tmp2:="33 32 31"; //ожидается что это 321 Вместо 3-ёх байт срать в сеть 8? Вот кто значит ддосы устраивает. type TBytes = array of Byte; ... function StringToBytes(const Value : String): TBytes; var sz:Cardinal; sz_byte:TBytes; begin sz:=Length(Value); SetLength(sz_byte, SizeOf(sz)); SetLength(Result, sz * SizeOf(Char) + SizeOf(sz)); if (Length(Result) > 0) and (Length(sz_byte) > 0) then begin Move(sz, sz_byte[0], Length(sz_byte)); Move(Value[1], Result[SizeOf(sz)], Length(Result)); Move(sz_byte[0], Result[0], Length(sz_byte)); end; end; function BytesToString(const Value: TBytes): String; begin SetLength(Result, Length(Value) div SizeOf(Char)); if Length(Result) > 0 then Move(Value[0], Result[1], Length(Value)); end; procedure TForm1.Button1Click(Sender: TObject); var buf:TBytes; begin buf:=StringToBytes('321'); client.SendBuffer(buf[0], Length(buf)); end; procedure TForm1.servUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle); var I, sz:Cardinal; data, sz_bytes:TBytes; begin sz:=0; SetLength(sz_bytes, SizeOf(sz)); AData.Read(sz_bytes[0], SizeOf(sz)); for I := 0 to Length(sz_bytes)-1 do sz := sz + Round(Power($100, I)) * sz_bytes[I]; SetLength(data, sz); AData.Read(data[0], sz); showmessage(BytesToString(data)); end; end. |
Сообщ.
#4
,
|
|
|
И снова здравствуйте.
Никогда. НИКОГДА! Никогда не отправляйте в сеть сырые данные. Обязательно оборачивать их в некий протокол application-уровня. Хотя бы примитивный: сперва DWORD с длиной ожидаемых данных (тройка в данном случае), а затем уже байты контента. Причина проста: сеть - это асинхронная среда многих соединений. Поэтому её нельзя расценивать как некий pipe, где байты ходят ровно теми же порциями, как их отправили. Поэтому и появились такие решения как Protobuf и Apache Thrift (стандартизованные протоколы-сериализаторы для произвольных структур данных). |
Сообщ.
#5
,
|
|
|
Цитата Mr.Delphist @ Хотя бы примитивный: сперва DWORD с длиной ожидаемых данных (тройка в данном случае), а затем уже байты контента. У меня в примере так и есть. Добавлено Цитата Mr.Delphist @ сеть - это асинхронная среда многих соединений. Данное понимание приходит лишь с опытом, когда начинаются дропы пакетов по независящим от тебя причинам, и ты судорожно начинаешь дебажить. |