Jump to content
Turan Can

How do we know if the, TCP Socket connection is connected

Recommended Posts

Hello everyone,

 

How do we constantly check whether there is a connection in a TCP/IP connection?

 

windows sample, With what can I get android connection status? POSIX

 

function TGateSocket.IsConnected: Boolean;
var
  FDSet: Fd_Set;
  Tv: TimeVal;
  I: Integer;
begin
  Result := False;

  FD_ZERO(FDSet);
  _FD_SET(SockId, FDSet);
  Tv.tv_sec := 0;
  Tv.tv_usec := 500;

{$IFDEF MSWINDOWS}

  I := select(0, @FDSet, nil, nil, @Tv);

  if (I = SOCKET_ERROR) then
    Result := False

else

      if recv(FSockId, FDSet, -1, 0)  = 0 then
        Result := False
      else
        Result := True;

{$ENDIF}

{$IFDEF POSIX}

??

{$ENDIF}
end;

 

 

Edited by Turan Can

Share this post


Link to post

AFAIK this set of socket functions is identical in Win and Nix (both from Berkeley sockets).

I'm curious, what do you do by recv() with length=-1?

Share this post


Link to post

I have "recv -1" data, I check this. so I see if there is data or not :).
It's a nice method.

Share this post


Link to post

  FD_ZERO(FDSet);
  _FD_SET(SockId, FDSet);
  Tv.tv_sec := 0;
  Tv.tv_usec := 0;

  I := select(0, @FDSet, nil, nil, @Tv);

 

 

I -  I look before the connection. result = 0

 

sock..

connect..

I - After connecting, I see the result is still the same. result = 0

Share this post


Link to post
15 hours ago, Turan Can said:

How do we constantly check whether there is a connection in a TCP/IP connection?

Cross-platform, the only way is to perform an I/O operation on the socket and check for error.  On Windows, at least, a non-blocking socket can issue an asynchronous FD_CLOSE notification when the connection is closed, but you should still check I/O operations for errors, too.

15 hours ago, Turan Can said:

windows sample, With what can I get android connection status? POSIX

The same type of coding will work on POSIX, too.  The base BSD socket API, like select() and recv(), is common across multiple platforms.

15 hours ago, Turan Can said:

  I := select(0, @FDSet, nil, nil, @Tv);

  if (I = SOCKET_ERROR) then
    Result := False

else

      if recv(FSockId, FDSet, -1, 0)  = 0 then

Why are you passing your fd_set variable as the buffer for recv() to read into?  More importantly, you can't pass -1 as the size of the buffer to read into.  On Windows, the len parameter is an int, so it will at least compile with a length of -1, but semantically asking recv() to read -1 number of bytes makes no sense, and is not documented as a supported operation.  But worse, on other platforms, the len parameter is a size_t, which is an unsigned type, so passing in a length of -1 will wrap to a very large value and very bad things can happen!

 

Also, you are not checking to make sure that select() actually reports the socket is readable before then calling recv() on the socket.  Since you are only querying 1 socket, the return value of select() will be -1 on error, 0 on timeout (not readable), and 1 (readable).  Alternatively, since select() modifies the fd_set struct on output, you can check if your socket is still in the set after select() exits.

 

Also, you are not handling recv() reporting an error at all.

 

Either way, do keep in mind that you are performing an actual read, so any bytes that recv() does actually receive will not be available for subsequent reads, so you will have to buffer the bytes somewhere in memory so you can still use them later.

 

In most cases, implementing an IsConnected() type of function is really unnecessary and should be avoided.

 

  • Like 1

Share this post


Link to post
13 hours ago, Turan Can said:

I have "recv -1" data, I check this. so I see if there is data or not :).
It's a nice method.

No, it is an undefined method.  Calling recv() with a buffer length of -1 is undefined behavior, and AFAICS no platform actually defines what should happen with that input.

Edited by Remy Lebeau

Share this post


Link to post
11 hours ago, Turan Can said:

  FD_ZERO(FDSet);
  _FD_SET(SockId, FDSet);
  Tv.tv_sec := 0;
  Tv.tv_usec := 0;

  I := select(0, @FDSet, nil, nil, @Tv);

 

 

I -  I look before the connection. result = 0

 

sock..

connect..

I - After connecting, I see the result is still the same. result = 0

Because you are merely checking the socket for readability only.  If select() returns 0, it timed out, which in this case means the socket is not readable because it has no pending data, not even a graceful disconnect.  As long as connect() is successful and the socket doesn't report read/write errors, it is connected.

Share this post


Link to post

In brief: to really reliably check whether a socket is alive, you should implement keep-alive (ping-pong) mechanism.

OTOH, probably you don't need to know alive status at all, just control result of R/W functions.

Share this post


Link to post

This information is great.
So how do I do this on android? Is the connection active? How do I know this?
is there an example?

 

I get the correct results with "tcp, select".
but can you enlighten me with an example of how to do it on android?

Share this post


Link to post

Remy, please read my first post and look at the example.
I have no problems with Windows socket.


My problem is the link on android. Select () gives the same result whether or not there is a link.

All my problem is that the select does not give the correct result in andorid. Whether there is a connection or not, the result is 0.

Share this post


Link to post
16 hours ago, Turan Can said:

So how do I do this on android? Is the connection active? How do I know this?
is there an example?

 

I get the correct results with "tcp, select".
but can you enlighten me with an example of how to do it on android?

What makes you think it is any different for Android?  Most platforms use the same Berkeley-based socket API.  That is true for Windows.  That is true for Posix systems, like Linux (which Android runs on top of).  select(), recv(), these functions exist and behave the same on Android (when coding at the native layer, as you describe) as they do on Windows.

Edited by Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×