In socket programming in Linux I need to write data in socket but I don't know socket is open or close . how to I know that socket is open and close without read ?
printf("befor read%d\n", n);
bzero(buffer, MAX_SIZE_BUFFER);
n = read(sockfd, buffer, MAX_SIZE_BUFFER - 1);
printf("after read%d\n", n);
if (n <= 0)
{
break;
}
printf("befor write%d, s: %d \n", n , sockfd);
n = write(newsockfd, buffer, n);
if (n <= 0)
{
break;
}
I read from sockfd and I sure this connection is open . When to write buffer in newsockfd I don't know newsockfd is open or close how to check newsockfd is closed ?
I know problem . in middle of writing connection closed . for example write 1024 data in 500 connection closed and program closed. how to avoid this ?
periodically check the TCP connection status via client. status() - in case it is 0, close the connection. This works when the connection is closed correctly by client, however doesnt work when the connection is closed incorrectly (lost wifi - phone cant ask Photon first to close the connection).
The only way to tell if the socket has been disconnected is to send data over it. set the timeout on the server side socket and then have the client check in every so often within the timeout so if you set the client to check in every 10 seconds then set the timeout to say 30 seconds on the server socket.
Just use the KeepAlive like @toster-cx says and then use the Socket Connected status to check if the Socket is still connected. Set your receive timeout at the same timeout of the keepalive.
I use send() instead write() that handle no signal :
bzero(buffer, MAX_SIZE_BUFFER);
n = read(sockfd, buffer, MAX_SIZE_BUFFER - 1);
printf("after read%d\n", n);
if (n <= 0)
{
break;
}
n2 = send(newsockfd, buffer, n, MSG_NOSIGNAL);
if (n2 == -1)
{
close(sockfd);
close(newsockfd);
return;
}
if (n2 != n)
{
break;
}
The way to check if you can write to a socket is, surprisingly, to try and write to it :-)
If the socket has been closed, you will get a -1
return code from write
and you can examine errno
to see what the problem was.
If the socket is still valid but you just can't write any data at the moment, write
will return 0. The read
call also behaves in a similar fashion, returning -1
if there's a problem.
Basically, for write
:
-1
, there's been a problem and you should check errno
to see if it's recoverable or fatal.0
, then you can't write anything at the moment (may be a network backlog or some other problem but definitely not (yet) fatal).Update: As caf has pointed out in the comments, I forgot to take into account the signal handling. You have to ignore the broken pipe signal or write
will fail internally by raising that signal.
You can do this by inserting:
struct sigaction new_actn, old_actn;
new_actn.sa_handler = SIG_IGN;
sigemptyset (&new_actn.sa_mask);
new_actn.sa_flags = 0;
sigaction (SIGPIPE, &new_actn, &old_actn);
before starting to use the socket functions. You can then use:
sigaction (SIGPIPE, &old_actn, NULL);
to restore the previous signal handling.
Socket programming can be rather tricky, because you often don't know an error has occurred until much later.
For instance, if the machine you are writing to shuts down abnormally, the write call may succeed ( because you were able to write to your internal OS buffers ), only to fail during the close call.
Unless you have an application-layer way of verifying the socket is active ( i.e., sending a message and requiring a response within some time period ) you have no way of knowing. If you are using a standard protocol, something may already exist to handle errors.
So the short answer is that you need to check for error returns from pretty much every call that touches the socket ( read, write, close, etc... ).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With