Sending binary data with Indy through TCP\IP, how? - delphi

How to send a binary data with Indy components? Which of them is most suitable for this task? I've tried to use TIdTcpClient but it allows only to send strings.
I've found one reponce for that problem here but I don't get it.
It says about method Write(TIdBytes), but the answer is not clear for me. Does he meant Write to some instance of TIdBytes, and how to connect that instance with TIdTcpClient?
Thanks for any help.

The page you cite doesn't reproduce the messages very well. Here's what Remy really wrote:
SendCmd() is designed for textual commands/parameters only. You would have
to send the binary data after SendCmd() exited, and the server would have to
read the binary data after sending a response back to the client. For
example:
--- client ---
begin
IdTCPClient1.SendCmd('DoIt', 200);
// send binary data, such as with Write(TStream) or Write(TIdBytes)...
end;
The Write methods he was talking about are members of the TIdIOHandler class. Your TIdTCPConnection object has an instance of that class in its IOHandler property, and indeed that's what the SendCmd function uses to send its string.
The notation Write(TIdBytes) means to use the Write method that accepts a TIdBytes parameter for its input.
If the binary data is already in a stream or a dynamic array of bytes, then you can pass one of those directly to the Write method. There's also the WriteFile method that will send an entire external file if you provide the file's name. If you use the stream version, then you have the option of including the stream's length automatically.
If you don't have your data in one of those structures already, then you can either write the data piecemeal with the Write methods that accept variously sized integer types, or you can copy your data into a TMemoryStream and then pass that to Write.

Write is a method (or whatever it is called in Delphi) of TCPClient. Here's working code of what you want to do: http://delphi.about.com/od/internetintranet/l/aa012004a.htm. Should get you up & running in no time :)

Related

Delphi use memory stream to read lines

I have made a C++ program that uses ofstream to create 2 files in my disk: one is called details.obf and the other is records.txt. The file details has only 1 line inside (1 integer) and the file records.txt has a non fixed number of lines (they are all strings).
With the code below I can get the value inside the file details. It's pretty simple and I am using a MemoryStream.
m := TMemoryStream.Create;
try
try
m.LoadFromFile(TPath.Combine(TPath.GetHomePath, 'details.obf'));
m.Read(i, sizeOf(i));
//other stuff...
except
//...
end;
finally
m.Free;
end;
With the code below instead I am reading the content of the records file:
a := TStreamReader.Create('C:\Users\betom\Desktop\records.txt');
try
while not(a.EndOfStream) do
begin
Memo1.Lines.Add(a.ReadLine);
end;
finally
a.Free;
end;
In the second block of code I have used a different class (TStreamReader) and I have written that code looking at embarcadero's documentation. I had to use the while not(a.EndOfStream) do because the lenght of records.txt is unknown.
I have seen that MemoryStream (and other classes) are all subclasses of TStream. Why I cannot call something like while not(m.EndOfStream) do with m a TMemoryStream?
I cannot understand the difference between a MemoryStream and a StreamReader. From what I have understood the latter can read automatically all the values in a given range while the first cannot.
Note: I have read on the docs that I can have a TStreamReader and a TStreamWriter and both are fine when I need to create a file that contains some data. I just cannot understand what are memorystream used for if I have the same behavior with a StreamReader.
TStreamReader is a general purpose class for reading text/character data from any stream. It does not support any other form of data in a stream and is not intended for use with any other form of data.
A stream itself might be a file on disk or data on the network or data in memory. Different stream classes exist to provide stream-access to data from those different sources.
TMemoryStream exists specifically to provide access to data in memory as a sequence of bytes, which may be binary data or text/character data or a mixture of both.
To answer your actual question:
I have seen that MemoryStream (and other classes) are all subclasses
of TStream. Why I cannot call something like while not(m.EndOfStream) do
with m a TMemoryStream?
First a correction. It is correct that TMemoryStream and some other stream manipulating classes (e.g. TFileStream) inherit from TStream. That is however not the case with TStreamReader (and TStringReader). These inherit from TTextReader, which together with TTextWriter and its descendents TStreamWriter and TStringWriter mainly exist to provide familiar classes for .Net users.
Here's the hierarchy of some of the discussed classes:
TObject
TStream
TCustomMemoryStream
TMemoryStream
TBytesStream
TStringStream
THandleStream
TFileStream
TWinSocketStream
TOleStream
TTextReader
TStreamReader
TStringReader
TBinaryReader
The answer is that the property EndOfStream is declared in TStreamReader, iow in a different branch than TMemoryStream.
In TStream descendents you can use e.g. the Position and Size properties to determine if you are at the end of the stream.

Delphi: How to put the data from TStream into TStgMedium for OLE processing?

I need to manage OLE drag-drop operations with Delphi. Now I got a problem - I need to put some data from TStream into global TStgMedium (to send it through OLE methods using IDataObject).
I guess there should be some commonly used pattern to do this? Can you provide some sample code?
It's probably easiest to use TStreamAdapter to adapt a TStream instance into an IStream.
The other approach that leaps out is to pass an HGLOBAL to IDataObject.SetData but that would be somewhat inefficient for large streams.

Streaming multiple TObjects to a TMemoryStream

I need to store multiple objects (most of them are TObject/non persistent) to a TMemoryStream, save the stream to disk and load it back. The objects need to be streamed one after each other. Some kind of universal container.
At the moment I put all properties/fields/variables of an object into a record and save the record to stream. But I intend to use functions file WriteInterger, WriteString (see below), WriteBoolean, etc functions to save/load data from stream.
StreamReadString(CONST MemStream: TMemoryStream): string;
StreamWriteString(CONST MemStream: TMemoryStream; s: string);
However, it seems that I need to rewrite a lot of code. One of the many examples is TStringList.LoadFromStream that will not work so it needs to be rewritten. This is because TStringList needs to be the last object in the stream (it reads from current position to the end of the stream).
Anybody knows a library that provide basic functionality like this?
I am using Delphi 7 so RTTI is not that great.
See related post here
Btw, Delphi7 also has RTTI support, otherwise your forms (.dfm) could not be loaded :-)
If you use published properties, RTTI will work for you "out of the box".
Otherwise you have to do it yourself with a
procedure DefineProperties(Filer: TFiler); override;
You can take a look at how it's implemented in:
procedure TDataModule.DefineProperties(Filer: TFiler);
These are the only ways for object serialization.
But you could also try records: if you do not use array(strings are also arrays of char) or object properties, you can directly save and load a record to memory (stream, file, etc). I use this in my AsmProfiler to be able to read and write many (small) results very fast (array of record with some integer values can be saved and loaded with one Move/CopyMemory call!).
Which Delphi version? Delphi 2010 has new RTTI functionality, so you can use DeHL which has "Full generic serialization for all included types and collections".
Have you thought about using TReader and TWriter to fill your streams.
Why not use XML?
Write an XSD for the XML that defines the XML.
Generate a Delphi unit form that XSD using the XML Data Binding Wizard.
Put a bunch of your objects into that XML.
Save the XML to disk (or stream it to some other medium).
For more info on XML and the XML Data Binding Wizard see this answer.
Edit:
Just map your objects to the interfaces/objects generated from the XSD; or use the objects/interfaces that have been generated.
That is usually far easier than hooking into the Delphi streaming mechanism (by either writing TPersistent wrappers with published properties around your objects, going the DefineBinaryProperty way, or the TReader/TWriter/DefineProperty way).
--jeroen

Parsing variable length descriptors from a byte stream and acting on their type

I'm reading from a byte stream that contains a series of variable length descriptors which I'm representing as various structs/classes in my code. Each descriptor has a fixed length header in common with all the other descriptors, which are used to identify its type.
Is there an appropriate model or pattern I can use to best parse and represent each descriptor, and then perform an appropriate action depending on it's type?
I've written lots of these types of parser.
I recommend that you read the fixed length header, and then dispatch to the correct constructor to your structures using a simple switch-case, passing the fixed header and stream to that constructor so that it can consume the variable part of the stream.
This is a common problem in file parsing. Commonly, you read the known part of the descriptor (which luckily is fixed-length in this case, but isn't always), and branch it there. Generally I use a strategy pattern here, since I generally expect the system to be broadly flexible - but a straight switch or factory may work as well.
The other question is: do you control and trust the downstream code? Meaning: the factory / strategy implementation? If you do, then you can just give them the stream and the number of bytes you expect them to consume (perhaps putting some debug assertions in place, to verify that they do read exactly the right amount).
If you can't trust the factory/strategy implementation (perhaps you allow the user-code to use custom deserializers), then I would construct a wrapper on top of the stream (example: SubStream from protobuf-net), that only allows the expected number of bytes to be consumed (reporting EOF afterwards), and doesn't allow seek/etc operations outside of this block. I would also have runtime checks (even in release builds) that enough data has been consumed - but in this case I would probably just read past any unread data - i.e. if we expected the downstream code to consume 20 bytes, but it only read 12, then skip the next 8 and read our next descriptor.
To expand on that; one strategy design here might have something like:
interface ISerializer {
object Deserialize(Stream source, int bytes);
void Serialize(Stream destination, object value);
}
You might build a dictionary (or just a list if the number is small) of such serializers per expected markers, and resolve your serializer, then invoke the Deserialize method. If you don't recognise the marker, then (one of):
skip the given number of bytes
throw an error
store the extra bytes in a buffer somewhere (allowing for round-trip of unexpected data)
As a side-note to the above - this approach (strategy) is useful if the system is determined at runtime, either via reflection or via a runtime DSL (etc). If the system is entirely predictable at compile-time (because it doesn't change, or because you are using code-generation), then a straight switch approach may be more appropriate - and you probably don't need any extra interfaces, since you can inject the appropriate code directly.
One key thing to remember, if you're reading from the stream and do not detect a valid header/message, throw away only the first byte before trying again. Many times I've seen a whole packet or message get thrown away instead, which can result in valid data being lost.
This sounds like it might be a job for the Factory Method or perhaps Abstract Factory. Based on the header you choose which factory method to call, and that returns an object of the relevant type.
Whether this is better than simply adding constructors to a switch statement depends on the complexity and the uniformity of the objects you're creating.
I would suggest:
fifo = Fifo.new
while(fd is readable) {
read everything off the fd and stick it into fifo
if (the front of the fifo is has a valid header and
the fifo is big enough for payload) {
dispatch constructor, remove bytes from fifo
}
}
With this method:
you can do some error checking for bad payloads, and potentially throw bad data away
data is not waiting on the fd's read buffer (can be an issue for large payloads)
If you'd like it to be nice OO, you can use the visitor pattern in an object hierarchy. How I've done it was like this (for identifying packets captured off the network, pretty much the same thing you might need):
huge object hierarchy, with one parent class
each class has a static contructor that registers with its parent, so the parent knows about its direct children (this was c++, I think this step is not needed in languages with good reflection support)
each class had a static constructor method that got the remaining part of the bytestream and based on that, it decided if it is his responsibility to handle that data or not
When a packet came in, I've simply passed it to static constructor method of the main parent class (called Packet), which in turn checked all of its children if it's their responsibility to handle that packet, and this went recursively, until one class at the bottom of the hierarchy returned the instantiated class back.
Each of the static "constructor" methods cut its own header from the bytestream and passed down only the payload to its children.
The upside of this approach is that you can add new types anywhere in the object hierarchy WITHOUT needing to see/change ANY other class. It worked remarkably nice and well for packets; it went like this:
Packet
EthernetPacket
IPPacket
UDPPacket, TCPPacket, ICMPPacket
...
I hope you can see the idea.

WSDL importer generates faulty server

I've been trying to get a soap server up that implements (is that the correct term?) a wsdl specification made by a third party. I have used Delphi's wsdl importer. (Part of) the generated code looks like this:
miniPortType = interface(IInvokable)
['{824D172A-9C1F-D202-5B21-4C324553BCF0}']
// Cannot unwrap:
// - Input element wrapper name does not match operation's name
function miniService(const aMessage: MiniMessageType): MiniAnswerType; stdcall;
end;
When called, the server says that "No method named 'MiniMessageType' is supported by interface 'miniPortType'".
I can only get this to work by making the name of the function and name of the main element of the message the same.
I think it should be possible to have different names. At least soapUI doesn't complain. And I actually have no choice but to implement the wsdl as is. Does anybody know how I can work around this?
I'm using Delphi 2007.
Thanks, Miel.
If I recall correctly, the SOAP interface is actually defined in a "table" at the bottom of the definitions, and it is this which is used to do the conversion between Delphi types and SOAP types in the communications. I've "corrected" this sort of thing in the past by manually changing the table building calls, but you have to be careful, and may also need to mangle the SOAP text at the appropriate point to make it all fit.

Resources