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:
83
network.c
83
network.c
@ -668,6 +668,89 @@ int NETReadTillTerm(mkChannel *self, long timeout,
|
|||||||
return 1;
|
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 ######################################*/
|
/* ################### UDP -functions ######################################*/
|
||||||
mkChannel *UDPOpen(int iPort)
|
mkChannel *UDPOpen(int iPort)
|
||||||
{
|
{
|
||||||
|
14
network.h
14
network.h
@ -76,10 +76,22 @@
|
|||||||
of hostname are copied to pComposter
|
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 ******************************** */
|
/* *********************** DATA TRANSFER ******************************** */
|
||||||
|
|
||||||
int NETWrite(mkChannel *self, char *buffer, long lLen);
|
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.
|
false otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user