Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Socket Connecting in OnError problem

Posted on 2004-10-21
8
Medium Priority
?
1,549 Views
Last Modified: 2008-01-09
Need some advice...

When using the OnError event to catch errors on a TClientSocket, how
would one connect if the error was because the socket wasn't connecting?

procedure TForm1.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  repeat
    Sleep(1000);
    TClientSocket(Socket).Active := True;
  until TClientSocket(Socket).Active;
end;


In the above, if the socket can't connect the second time Active is set
to true, the OnError is never fired.

Any tips on how to handle this?
0
Comment
Question by:EddieShipman
[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
  • 3
  • 3
  • 2
8 Comments
 
LVL 1

Expert Comment

by:sokpas
ID: 12370074
I think you have to reconsider your error handling block.
You have to decide prior to sending to the event handler routine if it is a connection error or not and retry connection outside the error handler, so the event can be retriggered.
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 12370225
You lost me  ;-(
0
 
LVL 1

Accepted Solution

by:
sokpas earned 500 total points
ID: 12374035
Sorry for my bad english, :)
After carefully reading again your question and the snippet, I see that you should change the error code to 0 to prevent the socket from raising an exception after successfully connecting. So

procedure TForm1.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  repeat
    Sleep(1000);
    If Not TClientSocket(Socket).Active Then TClientSocket(Socket).open;
  until TClientSocket(Socket).Active;
  ErrorCode:=0;
end;

Alltrough you should add code for checking the ErrorEvent type if it was an eeConnect or not. Thus not trying to reconnect an allready open connection.
0
Technology Partners: 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!

 
LVL 26

Author Comment

by:EddieShipman
ID: 12374402
Nope, still not working.
0
 
LVL 1

Expert Comment

by:sokpas
ID: 12374936

Then you must try this solution:

You should not try to reconnect on the OnError event. In the connection part of your code you should do something like:

....
Breakout:=False;
RetriesCnt:=0;
Repeat
    Socket.Open;
    If Not Socket.Active then
    begin
           Sleep(1000);
           Inc(RetriesCnt);
     end;
Until Socket.Active or (RetriesCnt>10);
.....
0
 
LVL 8

Expert Comment

by:gmayo
ID: 12378998
The way I do it is to have a timer running which periodically checks the socket connection. If the socket has not connected, then it sets Active to true. If the OnError fires then the reconnecttimer is reset. In the extract below, OneCycle is called once per second.

type
      TARSIF = class
      private
            ClientSocket : TClientSocket;
            SocketReconnectTime      : cardinal;
            ....
      end;


procedure TARSIF.OnSocketError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
      ErrorCode := 0;
      SocketReconnectTime := GetTickCount + 5000;
end;

procedure TARSIF.OneCycle;
var
      idx : integer;
begin
      if (ClientSocket = nil) or (Assigned(ClientSocket) and (ClientSocket.Socket.Connected = false))
      and (GetTickCount >= SocketReconnectTime)
      then CreateSocket;
end;

procedure TARSIF.CreateSocket;
begin
      if not Assigned(ClientSocket) then begin
            ClientSocket := TClientSocket.Create(fOwner);
            ClientSocket.Address := TheSDS.fConfig.ARSAddress;
            ClientSocket.Port := TheSDS.fConfig.ARSPort;
            ClientSocket.OnConnect := OnSocketConnect;
            ClientSocket.OnDisconnect := OnSocketDisconnect;
            ClientSocket.OnError := OnSocketError;
            ClientSocket.OnRead := OnSocketRead;
      end;
      if (ClientSocket.Address <> '') and (ClientSocket.Port <> 0) then ClientSocket.Active := true;
      SocketReconnectTime := GetTickCount + 5000;
end;


Geoff M.
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 12380541
Would this hog resources? What if the socket is disconnected between timer intervals and you try to read then. I'm having trouble calling a
Connect in the OnError, if ther is another error, it never reenters the OnError.
0
 
LVL 8

Expert Comment

by:gmayo
ID: 12382533
The socket won't read because it's disconnected. We use this for software which can run for days at a time - no problems. Bear in mind I haven't pasted the entire unit, so I might have missed one or two pertinent things... thinking about it I haven't pasted the OnDisconnect event which does some stuff. Can't do that til Monday now, sorry.

I have tried to call the Connect in OnError and that *does* cause errors. I can't remember specifically, something like stack overflow or out of resources. Sockets are funny things - treat them with care. For example, you can't write to a socket whilst in an OnRead event. We do a lot of socket stuff, all with TClientSocket and TServerSocket, and these are things we've learnt the hard way over time. We can't use the newer stuff because of legacy software.

Geoff M.
0

Featured Post

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.

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…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
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…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

610 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