From: Dani on
Hi, i want known if this code is correct to receive data of any
dimension. I used this to call a procedure on the server (write in
delphi 2007 e Indy that is fully funcionally to another client but
client write in delphi and run on windows) that return a large ammount
of data other 1460 byte. The call return only first 1460 byte without
error .. ?!?!?! I used VS2005 e CF 2.0 on iPaq 214 but the result is the
same on iPaq

string response, user, psw;
int lunghezzamessaggio;
user = "user";
psw = "xxxxxxx";
IPAddress serverIP = IPAddress.Parse(txtHost.Text);
TcpClient client = new TcpClient();
client.Connect(new IPEndPoint(serverIP, 8000));

NetworkStream strm = client.GetStream();

//So che il server invia un messaggio di benvenuto e lo leggo
byte[] bytes = new byte[client.ReceiveBufferSize];
strm.Read(bytes, 0, (int)client.ReceiveBufferSize);
response = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
txtRX.Text += "ILSERVER: " + response + "\r\n";
//ILSERVER: Sei connesso
//uso l'autenticazione e attendo risposta dal server
StreamWriter writer = new StreamWriter(strm);
writer.Write(":auth=>" + user + " , " + psw + "\r\n");
writer.Flush();
//attendo il messaggio del server che mi autentica.
while (!client.GetStream().DataAvailable)
{ }
lunghezzamessaggio = client.Client.Available;
strm.Read(bytes, 0, (int)client.ReceiveBufferSize);
response = Encoding.ASCII.GetString(bytes, 0,
lunghezzamessaggio);

if (response.Equals("Autenticato"))
{
//se ok chiedo al server il file
writer.Write("file\r\n");
writer.Flush();
//ho richiesto un file di 169 Kb seriale (senza ritorno a capo tra le righe)
while (!client.GetStream().DataAvailable)
{ }
lunghezzamessaggio = client.Client.Available;
byte[] bytesFile = new byte[client.ReceiveBufferSize];
txtRX.Text += "Receive Buffer Size: " +
client.ReceiveBufferSize.ToString() + "\r\n";
//ReceiveBufferSize = 32768 ??????????
strm.Read(bytes, 0, (int)client.ReceiveBufferSize);
response = Encoding.ASCII.GetString(bytes, 0,
lunghezzamessaggio);
txtRX.Text += "Lunghezza Dati in ricezione: " +
lunghezzamessaggio.ToString() + "\r\n";
//Lunghezza dati in ricezione: 1460 ???????
strm.Close();
client.Close();
txtRX.Text += "ILSERVER: " + response + "\r\n";
txtRX.Text += "Totale byte ricevuti: " +
lunghezzamessaggio.ToString() + "\r\n";
//Totale byte ricevuti: 1460
}
else
{
strm.Close();
client.Close();
}

The delphi code:

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
Memo1.Lines.Add('Client Connesso.');
AContext.Connection.IOHandler.Write('Sei connesso'+#13#10);
end;

procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
begin
Memo1.Lines.Add('Client Disconnesso')
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var ms: string;
FileStream: TStringList;
begin
ms:=AContext.Connection.IOHandler.ReadLn;
if ms = 'Quit' then begin
AContext.Connection.IOHandler.Write('Fine trasmissione'+#13#10);
AContext.Connection.Disconnect;
Memo1.Lines.Add('Il client ha inviato il comando Quit e verr�
disconnesso.');
end
else if LeftStr(ms,7) = ':auth=>' then begin //l'autenticazione � finta.
AContext.Connection.IOHandler.Write('Autenticato');
Memo1.Lines.Add(ms);
Memo1.Lines.Add('Il client ha inviato l''autenticazione ed �
connesso');
end
else if LeftStr(ms,4) = 'file' then begin
Memo1.Lines.Add('Il client ha richiesto "file"');
OpenDialog1.Execute();
if OpenDialog1.FileName <> '' then
begin
FileStream := TStringList.Create();
FileStream.LoadFromFile(OpenDialog1.FileName);
AContext.Connection.IOHandler.Write(FileStream.Text);
Memo1.Lines.Add('"file" gli � stato inviato:');
Memo1.Lines.Add(FileStream.Text);
Memo1.Lines.Add('Inviate righe '+ IntToStr(FileStream.Count));
end
else begin
AContext.Connection.IOHandler.Write('Il file non � leggibile.');
end;
end;
end;

HELP

Dani
From: Matt Evans on
As Paul has mentioned in a different message, the network driver may
not give you 32768 bytes in one go, and the DataAvailable property may
be false even though you haven't received 32768 bytes.

I would suggest that you keep trying to read data for a set length of
time, rather than until DataAvailable is false


On Feb 25, 7:49 pm, Dani <nos...(a)tin.it> wrote:
> Hi, i want known if this code is correct to receive data of any
> dimension. I used this to call a procedure on the server (write in
> delphi 2007 e Indy that is fully funcionally to another client but
> client write in delphi and run on windows) that return a large ammount
> of data other 1460 byte. The call return only first 1460 byte without
> error .. ?!?!?! I used VS2005 e CF 2.0 on iPaq 214 but the result is the
> same on iPaq
>
>              string response, user, psw;
>              int lunghezzamessaggio;
>              user = "user";
>              psw = "xxxxxxx";
>              IPAddress serverIP = IPAddress.Parse(txtHost..Text);
>              TcpClient client = new TcpClient();
>              client.Connect(new IPEndPoint(serverIP, 8000));
>
>              NetworkStream strm = client.GetStream();
>
>        //So che il server invia un messaggio di benvenuto e lo leggo
>                     byte[] bytes = new byte[client.ReceiveBufferSize];
>              strm.Read(bytes, 0, (int)client.ReceiveBufferSize);
>              response = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
>              txtRX.Text += "ILSERVER: " + response + "\r\n";
>             //ILSERVER: Sei connesso
>              //uso l'autenticazione e attendo risposta dal server
>              StreamWriter writer = new StreamWriter(strm);
>              writer.Write(":auth=>" + user + " , " + psw + "\r\n");
>              writer.Flush();
>         //attendo il messaggio del server che mi autentica.
>              while (!client.GetStream().DataAvailable)
>              { }
>              lunghezzamessaggio = client.Client.Available;
>              strm.Read(bytes, 0, (int)client.ReceiveBufferSize);
>              response = Encoding.ASCII.GetString(bytes, 0,
> lunghezzamessaggio);
>
>              if (response.Equals("Autenticato"))
>              {
>                  //se ok chiedo al server il file
>                  writer.Write("file\r\n");
>                  writer.Flush();
> //ho richiesto un file di 169 Kb seriale (senza ritorno a capo tra le righe)
>                  while (!client.GetStream().DataAvailable)
>                  { }
>                  lunghezzamessaggio = client.Client.Available;
>                  byte[] bytesFile = new byte[client.ReceiveBufferSize];
>                  txtRX.Text += "Receive Buffer Size: " +
> client.ReceiveBufferSize.ToString() + "\r\n";
>                 //ReceiveBufferSize = 32768 ??????????
>                  strm.Read(bytes, 0, (int)client.ReceiveBufferSize);
>                  response = Encoding.ASCII.GetString(bytes, 0,
> lunghezzamessaggio);
>                  txtRX.Text += "Lunghezza Dati in ricezione: " +
> lunghezzamessaggio.ToString() + "\r\n";
>                 //Lunghezza dati in ricezione: 1460 ???????
>                  strm.Close();
>                  client.Close();
>                  txtRX.Text += "ILSERVER: " + response + "\r\n";
>                  txtRX.Text += "Totale byte ricevuti: " +
> lunghezzamessaggio.ToString() + "\r\n";
>                 //Totale byte ricevuti: 1460
>              }
>              else
>              {
>                  strm.Close();
>                  client.Close();
>              }
>
> The delphi code:
>
> procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
> begin
>    Memo1.Lines.Add('Client Connesso.');
>    AContext.Connection.IOHandler.Write('Sei connesso'+#13#10);
> end;
>
> procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
> begin
>    Memo1.Lines.Add('Client Disconnesso')
> end;
>
> procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
> var ms: string;
>    FileStream: TStringList;
> begin
>    ms:=AContext.Connection.IOHandler.ReadLn;
>    if ms = 'Quit' then begin
>      AContext.Connection.IOHandler.Write('Fine trasmissione'+#13#10);
>      AContext.Connection.Disconnect;
>      Memo1.Lines.Add('Il client ha inviato il comando Quit e verrà
> disconnesso.');
>      end
>    else if LeftStr(ms,7) = ':auth=>' then begin //l'autenticazione è finta.
>      AContext.Connection.IOHandler.Write('Autenticato');
>      Memo1.Lines.Add(ms);
>      Memo1.Lines.Add('Il client ha inviato l''autenticazione ed è
> connesso');
>      end
>    else if LeftStr(ms,4) = 'file' then begin
>      Memo1.Lines.Add('Il client ha richiesto "file"');
>      OpenDialog1.Execute();
>      if OpenDialog1.FileName <> '' then
>      begin
>        FileStream := TStringList.Create();
>        FileStream.LoadFromFile(OpenDialog1.FileName);
>        AContext.Connection.IOHandler.Write(FileStream.Text);
>        Memo1.Lines.Add('"file" gli è stato inviato:');
>        Memo1.Lines.Add(FileStream.Text);
>        Memo1.Lines.Add('Inviate righe '+ IntToStr(FileStream.Count));
>      end
>      else begin
>        AContext.Connection.IOHandler.Write('Il file non è leggibile.');
>      end;
>    end;
> end;
>
> HELP
>
> Dani

From: Dani on
Ok i have problem. How can i implement a good method to receive
multipacket (to overcome the limit of 32768 byte) through tcpclient ? ES:

Client: i want to connect
Server: Hello
Client: command
Server: ok X packet
Client: send me
do
Server: send packet
client: receive packet
client: ok
loop x packet
client: if x packet received send ok and disconnected then error.

But what i use to rebuild packet and where store data of any dimension ?
Server side i have not problem but client side somes suggestions ?!

Matt Evans ha scritto:
> As Paul has mentioned in a different message, the network driver may
> not give you 32768 bytes in one go, and the DataAvailable property may
> be false even though you haven't received 32768 bytes.
From: Matt Evans on
It's easier if you know what the server is going to send you, for
example, if you know each packet is 4000 bytes, or a packet has a
termination byte then you just loop around reading bytes from the
stream until you have 4000 or have received the termination byte, then
you know you have a full packet. If you don't receive it with a set
amount of time then something could have gone wrong.

in your example:

Server: sends 65535 bytes
do
Client: asks to recieve 32768 bytes
Client: actually receives x bytes, adds to a buffer, checks to see if
packet is complete, yes? exit loop
Client: has too much time passed? yes? exit loop
loop
Client: has timeout occurred? Yes: then there is an error, no? got a
packet...

On Mar 3, 6:49 pm, Dani <nos...(a)tin.it> wrote:
> Ok i have problem. How can i implement a good method to receive
> multipacket (to overcome the limit of 32768 byte) through tcpclient ? ES:
>
> Client: i want to connect
> Server: Hello
> Client: command
> Server: ok X packet
> Client: send me
> do
> Server: send packet
> client: receive packet
> client: ok
> loop x packet
> client: if x packet received send ok and disconnected then error.
>
> But what i use to rebuild packet and where store data of any dimension ?
> Server side i have not problem but client side somes suggestions ?!
>
> Matt Evans ha scritto:
>
>
>
>
>
> > As Paul has mentioned in a different message, the network driver may
> > not give you 32768 bytes in one go, and the DataAvailable property may
> > be false even though you haven't received 32768 bytes.

From: Dani on
Ok Mat,
i tryed to implement this solution and i solve with one loop that inside
send a server another request with bytes offset, until the packet it's
not complete. This is ok. The same method if i send to the server a
packet over buffer dimension.
Thank's.
> It's easier if you know what the server is going to send you, for
> example, if you know each packet is 4000 bytes, or a packet has a
> termination byte then you just loop around reading bytes from the
> stream until you have 4000 or have received the termination byte, then
> you know you have a full packet. If you don't receive it with a set
> amount of time then something could have gone wrong.
>
> in your example:
>
> Server: sends 65535 bytes
> do
> Client: asks to recieve 32768 bytes
> Client: actually receives x bytes, adds to a buffer, checks to see if
> packet is complete, yes? exit loop
> Client: has too much time passed? yes? exit loop
> loop
> Client: has timeout occurred? Yes: then there is an error, no? got a
> packet...