0

クライアントとサーバーの両方に tidudpserver を使用しています。以下は、指定されたサーバーとクライアントのコードです。

unit udp_server;



procedure TForm4.serverUDPRead(AThread: TIdUDPListenerThread;
  AData: array of Byte; ABinding: TIdSocketHandle);
var
  buffer:tbytes;
  buffer2:tbytes;
  i:integer;
  ex_port:word;
  i_ip,ex_ip:string;
  t: string;
begin
   ex_ip:=abinding.PeerIP;      //public_ip
   ex_port:=abinding.PeerPort;   //public_port

   //byte  to string
   setlength(i_ip,length(adata) div 2);  

   // extract private ip from array of byte
   move(Adata[0],i_ip[1],length(adata)); 

   // client profile  {object of tclient }
   user:=tclient.create(ex_ip,ex_port,i_ip,0,''); 
   //copying public and private    endpoints to tclient object


   setlength(buffer,sizeof(user));         
   move(user,buffer[0],sizeof(user)); // copying object to byte array 


   server.Sendbuffer(abinding.PeerIP,abinding.PeerPort,buffer); 
   // send client info to all connected clients(is this correct way of sending buffer(byte array)?)
end;

onudpreadこれは、指定されたクライアント コードです。手順でサーバーから送信されたデータを読み取ることができません。バイト配列 (文字列と単語の型を含む) を読み取り可能なテキストに変換するにはどうすればよいですか?

unit udp_client;



procedure TForm4.server2UDPRead(AThread: TIdUDPListenerThread;
  AData: array of Byte; ABinding: TIdSocketHandle);
var
  dest:string;
  user2:tclient;// i had a tclient class in a separate file
  buffer:tbytes;
begin


  setlength(dest,length(adata));
  move(Adata[0],dest[1],length(adata));  // problem is over here ,is this correct?
end;

クライアントから送信されたプライベート IP

              ip:=getipaddress; //call private ip function taken from (http://delphi.about.com/od/networking/l/aa103100a.htm)

              setlength(i_ip,length(ip)*2);

              move(ip[1],i_ip[0],length(i_ip));

              server2.Sendbuffer('host',port,i_ip); 

クライアントが情報(パブリック/プライベートIP/ポート)をサーバーに送信する必要があるため、UDPホールパンチングを実行したい.サーバーはクライアント情報を交換し、チャットできるはずです.データ配列がすべてのデータを受信して​​いるため、混乱していますIPとテキストメッセージが混ざり合ってしまいますか?現在、中国語のようなゴミの値を受け取っています.

4

2 に答える 2

3

このコードにはいくつかの問題があります。

Move()サーバー コードでは、受信したデータを にコピーするときに、間違った Size 値を に渡していますString。を呼び出すときはSizeOf(Char)=2考慮していますが、呼び出すときは考慮してSetLength()いませんMove()。またSizeof(Char)、受信したデータが最初から UTF-16 である場合にのみ、考慮するのが正しいです (受信したデータが実際にどのように見えるかを示していませんでした)。

より大きな問題は、オブジェクトをクライアントに送信しようとしていて、それがうまくいかないことです。オブジェクトの個々のデータ メンバーをフラットな転送可能な形式にシリアル化し、代わりにそのデータを送信する必要があります。たとえば、IdGlobalユニットにはデータ <-> バイト変換 (ToBytes()オーバーロード、BytesTo...()オーバーロード、CopyTId...()オーバーロードなど) を実行するために使用できる多くの関数があります。TIdBytesしたがって、オブジェクトのすべてのデータを保持するのに十分な大きさの 1 つを割り当て、データを入力してから送信することができます。受信したら、再度個々の値に分割します。そのすべてを実際にどのように行うかは、最初に送信しようとしているデータの種類によって異なります (それも示していません)。

より具体的な例が必要な場合は、実際にやり取りしようとしているデータの種類を説明する必要があります。

于 2013-08-03T03:13:37.310 に答える
0

StringOf 関数を使用してみてください。TBytes タイプで動作します。

于 2013-08-03T07:59:52.227 に答える