Indy9のTIdUDPClient,TIdUDPServerで送受信を
したいのですがうまくいきません
SendBufferでクライアントからデータを送って
サーバーで受け取ったときに値がいつも変化してしまいます
原因がさっぱり分かりません
以下にソースを書きますが間違っているのでしょうか?
(クライアントのHostはLocalHostにしています)
procedure TForm1.Button1Click(Sender: TObject);
var
data: TMemoryStream;
i: Integer;
begin
data:=TMemoryStream.Create;
i:=1;
data.WriteBuffer(i,1);
IdUDPClient1.SendBuffer(data,1);
data.Free;
end;
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
Data: TMemoryStream;
i: Integer;
begin
Data:=TMemoryStream.Create;
Data.CopyFrom(AData,AData.Size);
Data.Position:=0;
Data.ReadBuffer(i,1);
Label1.Caption:=IntToStr(i);
Data.Free;
end;
> IdUDPClient1.SendBuffer(data,1);
送り側(TMemoryStream の使い方)が完全にまちがっていますね。
IdUDPClient1.SendBuffer(data^,1);
> data.WriteBuffer(i,1);
> IdUDPClient1.SendBuffer(data,1);
送り側のこの部分ですけど位置を元に戻してください
data.WriteBuffer(i,1);
data.Position := 0; // ←追加
IdUDPClient1.SendBuffer(data,1);
TMemoryStream の使い方を理解して使用する場合は
注意してください。うまく動かないときには型と位置の
確認をすることです。
> Data:=TMemoryStream.Create;
> Data.CopyFrom(AData,AData.Size);
> Data.Position:=0;
> Data.ReadBuffer(i,1);
> Label1.Caption:=IntToStr(i);
> Data.Free;
おせっかいですが、無駄なことしてますね
わざわざData を作ることも、コピーすることも必要ないかと・・・
AData.Position := 0;
AData.ReadBuffer(i, 1);
> data:=TMemoryStream.Create;
> i:=1;
> data.WriteBuffer(i,1);
> IdUDPClient1.SendBuffer(data,1);
> data.Free;
もうひとつおせっかいでしょうが
このそーすでは以下ですみそうです。
IdUDPClient1.SendBuffer(i, 1);
返信ありがとうございます
以下のようにソースを直しましたがやはり値が変動してしまいます
たまに正しい値になりますが・・
まだ何か問題があるのでしょうか?
ちなみにバイナリデータを送受信できれば
TMemoryStreamを使わなくてもいいのですが
他によい方法があれば教えていただきたいです
procedure TForm1.Button1Click(Sender: TObject);
var
data: TMemoryStream;
i: Integer;
begin
i:=StrToInt(Edit1.Text);
data:=TMemoryStream.Create;
data.WriteBuffer(i,1);
data.Position := 0;
IdUDPClient1.SendBuffer(data.Memory^,1);
data.Free;
end;
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
i: Integer;
begin
AData.Position := 0;
AData.ReadBuffer(i, 1);
Label1.Caption:=IntToStr(i);
end;
プログラムの目的がわからないので確認ですが、
このプログラムで送信できるのは i の値の下位バイトの1バイトです
i = $12345678 (i は Integer なので4バイト)のデータを送信すると、
受信できる i = $78 です。
例>
送信 受信
i := 0..255; i := 0..255;
i := 256..511; i := 0..255;
もし、送信と、受信の i を同じにしたいのであれば、
基本的にソース(考え方)がまちがっているのですが、
そうじゃないですよね?
例のように送受信がされていいのですが、
iに1を入れて送信すると受信したときに
ラベルに12452233や13238787のような数字が表示されます
何度かボタンをクリックしていると1になるときもあります
iに1バイトしか読んだけでは32ビット整数の上位24ビットには何が入っているか保証されないよ・・・ということなのですが
---
i :=0;
AData.ReadBuffer(i, 1);
---
としたらどう?
Integer がわかっていないようですね。
メモリ上 ・・・ 12 34 56 78 90 AB CD EF ・・・
← i →
i は Integer なので4バイトです
i := 1 ・・・ 12 34 01 00 00 00 CD EF ・・・
メモリ上は上位下位が反転して入ります。
i の1バイトを送信すると1が送られます。
理論上間違っていないが、通常1バイトを送るなら
i: Integer; の宣言を SendByte: Byte; として
data.WriteBuffer(i,1); → data.WriteBuffer(SendByte,1);
または data.WriteBuffer(SendByte, SizeOf(Byte));
とします。
受信側です。
メモリ上 ・・・ AA BB 11 22 33 44 55 66 ・・・
← i →
ここで、AData.ReadBuffer(i, 1); が実行されると
メモリ上 ・・・ AA BB 01 22 33 44 55 66 ・・・
↑
i の先頭番地のデータ1バイトが変わる
つまり、 i の値は $44332201 となります。
強いていえば、あなたの仕様を損なわないようにするには
i := 0; ← 追加してください
AData.ReadBuffer(i, 1);
お分かり?
とりあえずやりたいことはできるようになりました
ありがとうございます
原因は何となく分かるような分からないような・・
もっと勉強します
ツイート | ![]() |