Solved

SendBuf and ReceiveBuf

Posted on 2004-04-06
9
2,985 Views
Last Modified: 2008-02-20
Hello, here is part of my program,

function Tdhskmus1.HostIPIO(data: PChar; len: integer): integer;
var
      iphostcmd, respcmd: TIPHOSTCMD;
Begin
  result := 0;
  HostIP_connect; //open the socket connection
  ....
  rc := fmtIPCmd(Desrec, iphostcmd); //return number of bytes to be sent
  showmessage(format('I AM ALIVE ()', []));
  rc := host_socket.socket.SendBuf(iphostcmd, rc);
  showmessage(format('rc = %d', [rc]));
  host_socket.socket.ReceiveBuf(respcmd, sizeof(respcmd));
  ...
  host_socket.close;
end;

My question is I have to insert those 2 "showmessage" code for the program to work properly, otherwise  sendbuf and receivebuf will fail (sendbuf writes nothing). I don't understand why this would happen. I have tried insert other codes in the middle, but it appears to be only message box can make it work. Could someone tell me how to resolve it? I don't want user keep pressing enter when the program is running!
Thank you.
0
Comment
Question by:kc2592
  • 3
  • 2
9 Comments
 

Expert Comment

by:TomGrills
ID: 10764709
From your code, it appears that you might not be waiting for the socket connection to be completed before sending and receiving...  putting the showmessage in between the lines causes the app to pause and allows for the connection to be completed...  perhaps you should put the code into the OnConnect event or start a timer event OnConnect that will periodically send the "I AM ALIVE" message....
0
 
LVL 9

Expert Comment

by:mocarts
ID: 10766926
hi!
if you are using TClientSocket, then try to set ClientType property to ctBlocking. That will enforce synchronous data exchange between server and client i.e. program will proceed to next line only when all data will be sent.
Read also Help (TClientSocket.ClientType) about how to avoid program freezing if server hangs, for example.

wbr, mo.
0
 

Author Comment

by:kc2592
ID: 10773364
I found that clientsocket.active property won't turn TRUE until my first showmessage code. I think that's why my sendbuf failed if I took out that code. But I thought when I established the connection, then active would be true. Any suggestion?  (I don't want my socket to be active when the application start up)
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 9

Expert Comment

by:mocarts
ID: 10774420
It's also because of ctNonBlocking ClientType. if you use nonblocking (asynchronous) connection, then execution of next line occurs immediately after connection witout waiting to connect to server host (i.e. sepparate thread is created). in nonblocking mode you should write OnRead and OnWrite events for read/write operations.
also ctNonBlocking is preferable way to perform communications. in neither case your server will respond to client while all client request is received.
Did you tried to set ClientType to ctBlocking?
0
 

Author Comment

by:kc2592
ID: 10780637
If I use OnWrite event to do sendbuf function, then in my function, how do I trigger the OnWrite event? Or I still do sendbuf in my function, then what to do in OnWrite event?

Thanks.
0
 
LVL 9

Accepted Solution

by:
mocarts earned 100 total points
ID: 10781396
you don't need to trigger any events - they will be triggered automatically by socket component.
here will be code template translated from your code sample:

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  respcmd: TIPHOSTCMD;
begin
  // if command sent then we can read server response
  if FCmdSent then
  begin
    Socket.ReceiveBuf(respcmd, sizeof(respcmd));
    Socket.Close;
    DoSomethingWithResponse(respcmd);
  end else
    raise Exception.Create('Unexpected data in client buffer!');
end;

procedure TForm1.ClientSocket1Write(Sender: TObject;
  Socket: TCustomWinSocket);
var
  iphostcmd: TIPHOSTCMD;
  rc: integer;
begin
  // if not already command sent
  if not FCmdSent then
  begin
    rc := fmtIPCmd(Desrec, iphostcmd); //return number of bytes to be sent
    rc := Socket.SendBuf(iphostcmd, rc);
    FCmdSent := True;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FCmdSent := False;
  ClientSocket1.Active := True;
end;

wbr, mo.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

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…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

706 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now