Re: [twsocket] Sending Record Type Data over tcp
Hello Alper, > I'm using LineMode, to receive all data sent. (My data size is 49b in total > and no string data in it) > Are there any conflicts i may encounter in the approach stated below? Yes, if your binary data contains the line end characters you use the your code will fail as Arno already mentioned. Second, if you do not receive your whole data, but only a part of it then your code will fail too. Also it is possible you receive your whole packet and a part (or whole) of the next packet (depending on speed of the transmitting prgram). > (I intend to replace Rcvd variable with a global one to prevent having > allocating it in every receive) Good, allocating each time will slow down and possible to have fragmented memory if you have hi speed transmission / reception. Not need to use a global, but a class variable will do the same (but that's probably what you mean). > if RcvdSize < 0 then exit; You may better change this to: if RcvdSize <= 0 then Exit; Because if you receive nothing (0) then you can exit here also. Somethime Winsock tell to receive and does not wants to give data (I think Winsock is a women ;-) > case Ord(Rcvd[0]) of // Choose data type > 0: begin > New(Data); > try > CopyMemory(Data, @Rcvd[1], SizeOf(TStatus)); Yes oke, but what if you have just received one byte here? Then this will fail. You can use LineMode but then you have to make sure the line end character(s) you want to use ar never in your data. Several approch ar possible, Look at my article on http://wiki.overbyte.be/wiki/index.php/Sending_and_receiving_data wich explain some of the possible approaches for binary data. --- Rgds, Wilfried [TeamICS] http://www.overbyte.be/eng/overbyte/teamics.html http://www.mestdagh.biz Tuesday, June 30, 2009, 18:29, Alper Albayrak wrote: > Yes, Im using TCP. > I solved my problem (at least in here) with replacing Move() into > CopyMemory() > I'm using LineMode, to receive all data sent. (My data size is 49b in total > and no string data in it) > Are there any conflicts i may encounter in the approach stated below? > (I intend to replace Rcvd variable with a global one to prevent having > allocating it in every receive) > Thank you for help and kind replies.. > procedure TMainForm.WSocket1DataAvailable(Sender: TObject; ErrCode: Word); > var > Rcvd: PChar; > RcvdSize: integer; > Data: PStatus; > begin > if ErrCode <> 0 then exit; > GetMem(Rcvd, 128); > with (Sender as TWSocket) do > try > RcvdSize := Receive(Rcvd, 128); > if RcvdSize < 0 then exit; > case Ord(Rcvd[0]) of // Choose data type > 0: begin > New(Data); > try > CopyMemory(Data, @Rcvd[1], SizeOf(TStatus)); > ... > except > Dispose(Data); > end; > end; > 1: begin > ... > end; > end; > finally > FreeMem(Rcvd); > end; > end; > -- > To unsubscribe or change your settings for TWSocket mailing list > please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket > Visit our website at http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] Sending Record Type Data over tcp
Some remarks: As Francois said, you need to check you received all the data. Your code don't check if RcvdSize is equal to your record data size. Why you need to copy the memory? If you are going to use it locally, at that procedure, just point your different records Data pointers to the Rcvd buffer. And why you don't use only one record, with variant part? TEmployee = record FirstName, LastName: string[40]; BirthDate: TDate; case Salaried: Boolean of True: (AnnualSalary: Currency); False: (HourlyWage: Currency); end; RTT -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] Sending Record Type Data over tcp
Alper Albayrak wrote: > Yes, Im using TCP. > I solved my problem (at least in here) with replacing Move() into > CopyMemory() > > I'm using LineMode, to receive all data sent. (My data size is 49b in > total and no string data in it) That is dangerous! Are you able to exclude that the LineEnd bytes will never be found in your binary data? I don't think so. ICS v7 contains a demo that shows one way to send binary data mixed with string data: http://svn.overbyte.be:8443/svn/ics/branches/icsv7/Delphi/Internet/OverbyteIcsBinCliDemo1.pas (http://wiki.overbyte.be/wiki/index.php/FAQ#How_to_get_ICS) > Are there any conflicts i may encounter in the approach stated below? > (I intend to replace Rcvd variable with a global one to prevent having > allocating it in every receive) A global buffer is the way to go. Do not use PChar for binary data but either TBytes, PByte or PAnsiChar, that makes it easier to convert the code to support Unicode later on. -- Arno Garrels -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] Sending Record Type Data over tcp
Is your data size fixed? If so, it might work. The method I suggested was for variable data size. Regards, SZ On Tue, Jun 30, 2009 at 7:29 PM, Alper Albayrak wrote: > Yes, Im using TCP. > I solved my problem (at least in here) with replacing Move() into > CopyMemory() > > I'm using LineMode, to receive all data sent. (My data size is 49b in total > and no string data in it) > Are there any conflicts i may encounter in the approach stated below? > (I intend to replace Rcvd variable with a global one to prevent having > allocating it in every receive) > > Thank you for help and kind replies.. > > procedure TMainForm.WSocket1DataAvailable(Sender: TObject; ErrCode: Word); > var > Rcvd: PChar; > RcvdSize: integer; > Data: PStatus; > begin > if ErrCode <> 0 then exit; > GetMem(Rcvd, 128); > with (Sender as TWSocket) do > try >RcvdSize := Receive(Rcvd, 128); >if RcvdSize < 0 then exit; > >case Ord(Rcvd[0]) of // Choose data type > 0: begin >New(Data); >try > CopyMemory(Data, @Rcvd[1], SizeOf(TStatus)); > ... >except > Dispose(Data); >end; > end; > > 1: begin > ... > end; >end; > finally >FreeMem(Rcvd); > end; > end; > -- > -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] Sending Record Type Data over tcp
Yes, Im using TCP. I solved my problem (at least in here) with replacing Move() into CopyMemory() I'm using LineMode, to receive all data sent. (My data size is 49b in total and no string data in it) Are there any conflicts i may encounter in the approach stated below? (I intend to replace Rcvd variable with a global one to prevent having allocating it in every receive) Thank you for help and kind replies.. procedure TMainForm.WSocket1DataAvailable(Sender: TObject; ErrCode: Word); var Rcvd: PChar; RcvdSize: integer; Data: PStatus; begin if ErrCode <> 0 then exit; GetMem(Rcvd, 128); with (Sender as TWSocket) do try RcvdSize := Receive(Rcvd, 128); if RcvdSize < 0 then exit; case Ord(Rcvd[0]) of // Choose data type 0: begin New(Data); try CopyMemory(Data, @Rcvd[1], SizeOf(TStatus)); ... except Dispose(Data); end; end; 1: begin ... end; end; finally FreeMem(Rcvd); end; end; -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] Sending Record Type Data over tcp
> My record type is like; > TData = record > age: integer; > end; > PData = ^TData; > > I send data as follows succesfully; > Send(Data, SizeOf(TData)); > > and receive; > Receive(Data, SizeOf(TData)); > > What i want to do is to send a couple of record types (seperately); and > distinguish them on the client side. > i tried moving data into a PChar variable, ant put some distinguisher in > front of data, but this didnt worked out, or i couldnt.. I will assume you are using TCP, not UDP. I see two problems in your design: 1) Receive will receive what is available, at most the size you specifyed. It is well possible that not all data are already arrived. It works in you case because you sent an integer (4 bytes) which is likely to arrive in one data packet. If you had larger data, it is likely it would be split into several packets and you would get several OnDataAvailable events. 2) TCP is a stream oriented connection. This means there is no record concept in the data stream. It is just a bidirectional byte stream, just like a simple file stream. The impact is that the receiver has no way to know you send 2 of your records seperately or a single large record. You must add yourself a delimiter between your records, or add a length field in front of your record. Please have a look at "TCP/UDP primer" available from http://wiki.overbyte.be/wiki/index.php/FAQ.Difference -- francois.pie...@overbyte.be Author of ICS (Internet Component Suite, freeware) Author of MidWare (Multi-tier framework, freeware) http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] Sending Record Type Data over tcp
Hello/Merhaba, Why don't you use the algorithm logic in HTTP and explicitly state how many bytes will follow in a header? for example this is how it is done in chunked encoding in HTTP (pseudo code): 10CRLF <10 bytes of data> 20CRLF <20 bytes of data> 0CRLF Regards, And an extra first record item, present in all records, used to identify the record type. But this is not a communications problem. If you are able to save your data to a file, and later load it reconstructing your records, use the same schema to send it (same as save to a file) and receive it (same as load it from a file) RTT -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] Sending Record Type Data over tcp
Hello/Merhaba, Why don't you use the algorithm logic in HTTP and explicitly state how many bytes will follow in a header? for example this is how it is done in chunked encoding in HTTP (pseudo code): 10CRLF <10 bytes of data> 20CRLF <20 bytes of data> 0CRLF Regards, SZ On Mon, Jun 29, 2009 at 6:02 PM, Alper Albayrak wrote: > My record type is like; > > TData = record > age: integer; > end; > PData = ^TData; > > > I send data as follows succesfully; > > Send(Data, SizeOf(TData)); > > > and receive; > > Receive(Data, SizeOf(TData)); > > > What i want to do is to send a couple of record types (seperately); and > distinguish them on the client side. > i tried moving data into a PChar variable, ant put some distinguisher in > front of data, > but this didnt worked out, or i couldnt.. > > Can someone help me out? > > Thanks.. > -- > -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
[twsocket] Sending Record Type Data over tcp
My record type is like; TData = record age: integer; end; PData = ^TData; I send data as follows succesfully; Send(Data, SizeOf(TData)); and receive; Receive(Data, SizeOf(TData)); What i want to do is to send a couple of record types (seperately); and distinguish them on the client side. i tried moving data into a PChar variable, ant put some distinguisher in front of data, but this didnt worked out, or i couldnt.. Can someone help me out? Thanks.. -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be