From: Dani on 25 Feb 2010 03:49 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 2 Mar 2010 17:27 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 3 Mar 2010 02:49 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 3 Mar 2010 20:09 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 4 Mar 2010 10:04 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...
|
Pages: 1 Prev: How to Detect file opening / close Next: this code failed ( tcpclient ) |