?
Solved

Send and receive a TMemoryStream

Posted on 2003-03-25
10
Medium Priority
?
445 Views
Last Modified: 2010-04-03
Hi,

I'm trying to send a memory stream that contains a picture through the network, using TClientSocket and TServerSocket. I found the SendStream procedure and my two computers are connected but I'm not able yet to recover what I sent. I tried with ReceiveBuf but this doesn't seem to work. Could someone help me with this ? How exactly should I do to send the MemoryStream and then to directly put its content into another MemoryStream when I receive it ? I would be grateful if someone could help as soon as possible. Thanks in advance.

P.S. : I work with Delphi 5.
0
Comment
Question by:matt_springs
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
10 Comments
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 8202682
switch to Indy - www.nevrona.com/indy
TCPClient/TCPServer - they have WriteStream and ReadStream
quite simple :)
0
 
LVL 3

Expert Comment

by:emadat
ID: 8203589
If you do not want to switch to Indy, you can use SendBuf and give it the stream as foolowing:

//     SockOut: TClientSocket;
//     OutStrm: TMemoryStream;
SockOut.Socket.SendBuf(OutStrm.Memory^, OutStrm.Size);

You can apply the same technique at the receiveing end. However; you need to set the strem size before receiving data by using

InStrm.SetSize(DataSize);
ReceiveBuf(InStrm.Memory^, DataSize);

Regards,
0
 

Expert Comment

by:marusaki
ID: 8203936
You could also use a TStringStream instead. Either copy the memory stream into the string stream or load the latter directly from your image source. Then use the method SendStr of the socket to send the DataString property of the string stream. At the other end you will use another string stream to restore the original stream.

Marius
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:matt_springs
ID: 8208659
I finally found another way to send my stream. With the FastNet components NMStrm and NMStrmServ. The PostIt procedure allowed me to send pictures and I receive them with the CaptureStream procedure. But the problem of this solution is that PostIt connects and disconnects for every sending. And I want to make continuous sending. So I made a permanent connection and tried to send the stream with SendStream but now, the program crashes saying that ''BM6....' is not a valid integer value. I don't understand why it's waiting a integer... Does anyone has an idea to help me ???
0
 
LVL 3

Expert Comment

by:emadat
ID: 8210929
Did you try my solution posted above?
It works for me
0
 

Author Comment

by:matt_springs
ID: 8213359
I havent tested your solution yet. That's the first thing I will do tomorrow morning and I will tell you if it works. Thanks a lot for your help ! ;-)
0
 

Author Comment

by:matt_springs
ID: 8216828
Hi, it doesn't work, it says it's not a correct bitmap;
I did what you said and added :

inStrm.write(instrm.memory^, datasize);
image1.picture.bitmap.loadfromstream(instrm);

where is the error or what exactly should I write in the send and receive procedures ? could you send me the source code you wrote?
0
 
LVL 3

Accepted Solution

by:
emadat earned 750 total points
ID: 8219651
Ok.. You are right.

I'm using this in a blocking threading mode.

However; here is another solution that uses Indy Sockets as "Lee_Nover" recommended:

You should have the following components:

Form1: TForm1
idServer: TIdTCPServer;
idClient: TIdTCPClient;
Image1: TImage;
Button1: TButton;

assuming you will be using port 9090, set these properties in the object inspector:

  idClient.Port = 9090
  idClient.Host = Server_IP_Address or Server_Host_Name
  idServr.DefaultPort = 9090
  idServr.Binding = :9090
  idServr.Active = True

//******************************************************************************
procedure TForm1.Button1Click(Sender: TObject);
var
     msSend: TMemoryStream;
begin
     idClient.Connect;
     image1.Picture.LoadFromFile(Image_File_Path);
     image1.Refresh;

     msSend := TMemoryStream.Create;
     try
          image1.Picture.Bitmap.SaveToStream(msSend);
          if idClient.Connected then begin
               idClient.WriteLn(IntToStr(msSend.Size));
               idClient.WriteStream(msSend);
          end;
     finally
          msSend.Free;
     end;
     idClient.Disconnect;
end;
//******************************************************************************
procedure TForm1.idServerExecute(AThread: TIdPeerThread);
var
     mS: TMemoryStream;
     S: String;
begin
     with AThread.Connection do begin
          S := ReadLn;
          mS := TMemoryStream.Create;
          try
               ReadStream(mS, StrToInt(S));
               mS.SaveToFile(_Received_File_);
          finally
               mS.Free;
          end;
     end;
end;
//******************************************************************************
0
 

Author Comment

by:matt_springs
ID: 8223332
Are you sure that it works ? I will try this afternoon. Isn't there any other way to do this with the classical Server & Client sockets from Delphi ?
0
 
LVL 3

Expert Comment

by:emadat
ID: 8224980
The last one I posted works fine.
I'm using the classic Server and Client from delphi in a Multithreading application; and they are doing fine. But I tried it in your case with no luck.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question