Add NETReconnect and NETReconnectWithFlags to recover a disconnected socket.

r1485 | dcl | 2007-02-15 07:48:49 +1100 (Thu, 15 Feb 2007) | 2 lines
This commit is contained in:
Douglas Clowes
2007-02-15 07:48:49 +11:00
parent 2de2a0394d
commit 418f5fb5d9
2 changed files with 96 additions and 1 deletions

View File

@ -668,6 +668,89 @@ int NETReadTillTerm(mkChannel *self, long timeout,
return 1;
}
/*---------------------------------------------------------------------------*/
int NETReconnectWithFlags(mkChannel* self, int flags)
{
int iRet;
int sock;
int oldopts;
/*
* Get the flags and close the old socket
*/
oldopts = fcntl(self->sockid, F_GETFL, 0);
close(self->sockid);
/* Reopen and try to get it on the olf fd */
sock = socket(AF_INET,SOCK_STREAM,0);
if (self->sockid != sock) {
iRet = fcntl(sock, F_DUPFD, self->sockid);
if (iRet != sock)
self->sockid = sock;
else
close(sock);
sock = self->sockid;
}
/* restore the old flags */
fcntl(self->sockid, F_SETFL, oldopts);
/* set socket non-blocking */
oldopts = fcntl(self->sockid, F_GETFL, 0);
if (/*(flags & 1) &&*/ !(oldopts & O_NONBLOCK))
fcntl(self->sockid, F_SETFL, oldopts | O_NONBLOCK);
/* try to reconnect */
iRet = connect(self->sockid,
(struct sockaddr *)&(self->adresse),
sizeof(struct sockaddr_in));
if (iRet < 0) {
if (errno == EINPROGRESS) {
if ((flags & 1)) {
iRet = 0; /* in progress */
} else {
fd_set rmask;
fd_set wmask;
struct timeval tmo = {1,0};
FD_ZERO(&rmask);
FD_ZERO(&wmask);
FD_SET(self->sockid, &rmask);
FD_SET(self->sockid, &wmask);
iRet = select(self->sockid+1, &rmask, &wmask, NULL, &tmo);
if (iRet < 0) /* error */
iRet = -1;
else if (iRet == 0) /* timeout */
iRet = 0; /* in progress */
else {
char reply[1];
if (FD_ISSET(self->sockid, &rmask)) {
iRet = recv(self->sockid, reply, 1, MSG_PEEK);
if (iRet <= 0)
iRet = -1; /* failure */
}
if (FD_ISSET(self->sockid, &wmask)) {
iRet = send(self->sockid, NULL, 0, 0);
if (iRet < 0)
iRet = -1; /* failure */
else
iRet = 1; /* success */
}
}
}
}
else /* other error */
iRet = -1; /* error */
}
else
iRet = 1; /* success */
if (iRet != 0 && !(oldopts & O_NONBLOCK))
fcntl(self->sockid, F_SETFL, oldopts);
return iRet;
}
int NETReconnect(mkChannel* self)
{
return NETReconnectWithFlags(self, 0);
}
/* ################### UDP -functions ######################################*/
mkChannel *UDPOpen(int iPort)
{

View File

@ -76,10 +76,22 @@
of hostname are copied to pComposter
*/
int NETReconnect(mkChannel* self);
/* If a connection has been lost, try to reconnect using the same
* socket id if possible. Blocks for up to one second.
* returns 0 if in progress, 1 on success, a negative value on error
*/
int NETReconnectWithFlags(mkChannel* self, int flags);
/* If a connection has been lost, try to reconnect using the same
* socket id if possible. If (flags & 1) do not block, use
* NETConnectFinished to check success.
* returns 0 if in progress, 1 on success, a negative value on error
*/
/* *********************** DATA TRANSFER ******************************** */
int NETWrite(mkChannel *self, char *buffer, long lLen);
/* writes data to socket self, returns True if succes,
/* writes data to socket self, returns True if success,
false otherwise.
*/