Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Send and receive a TMemoryStream

Posted on 2003-03-25
10
Medium Priority
?
463 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
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
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!

 

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Screencast - Getting to Know the Pipeline
Suggested Courses
Course of the Month10 days, 18 hours left to enroll

572 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