Solved

SendBuf and ReceiveBuf

Posted on 2004-04-06
9
3,002 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
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

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

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

Suggested Solutions

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
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…
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

808 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