I'm writing an ftp server and I've run into a problem. If the client waits too long between messages, I want to end the connection. As of now my program is set up like this:
Main thread (for controller input) spawns a server thread
Server thread listens for new connections and spawns threads for new clients
Client threads run net_read() in a loop, which blocks until data is received
Since net_read() blocks, I can't tell from within the client threads if I should end the connection until more data comes in so it unblocks, which could be never. So my solution was to create a watchdog thread that will periodically check to see when the last time data was received in each child thread, and if it was more than X minutes ago, net_close() the socket and "delete" the thread. But I can't seem to find a function to completely get rid of the thread, only to suspend it, unless it exits on its own accord.
Is there such a function? If not, what would be the most elegant solution?
LWP_CreateThread counterpart to stop thread execution?
Re: LWP_CreateThread counterpart to stop thread execution?
You have to make the socket nonblocking
Here's the connection code from libtinysmb (smb.c) which should help.
and the read data function which implements a timeout
Here's the connection code from libtinysmb (smb.c) which should help.
Code: Select all
static s32 do_netconnect(SMBHANDLE *handle)
{
u32 set = 1;
s32 ret;
s32 sock;
u64 t1,t2;
handle->sck_server = INVALID_SOCKET;
/*** Create the global net_socket ***/
sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if(sock==INVALID_SOCKET) return -1;
// Switch off Nagle with TCP_NODELAY
net_setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,&set,sizeof(set));
// create non blocking socket
ret = net_ioctl(sock, FIONBIO, &set);
if (ret < 0)
{
net_close(sock);
return ret;
}
t1=ticks_to_millisecs(gettime());
while(1)
{
ret = net_connect(sock,(struct sockaddr*)&handle->server_addr,sizeof(handle->server_addr));
if(ret==-EISCONN) break;
t2=ticks_to_millisecs(gettime());
usleep(1000);
if((t2-t1) > CONN_TIMEOUT) break; // usually not more than 90ms
}
if(ret!=-EISCONN)
{
net_close(sock);
return -1;
}
handle->sck_server = sock;
return 0;
}
Code: Select all
/**
* smb_recv
*
* blocking call with timeout
* will return when ANY data has been read from socket. Number of bytes read is returned.
* OR timeout. Timeout will return -1
* OR network error. -ve value will be returned
*/
static s32 smb_recv(s32 s,void *mem,s32 len)
{
s32 ret,read,readtotal=0;
u64 t1,t2;
t1=ticks_to_millisecs(gettime());
while(len > 0)
{
read=len;
if(read>SMB_MAX_NET_READ_SIZE)
read=SMB_MAX_NET_READ_SIZE; // optimized value
ret=net_recv(s,mem+readtotal,read,0);
if(ret>0)
{
readtotal+=ret;
len-=ret;
if(len==0) return readtotal;
}
else
{
if(ret!=-EAGAIN) return ret;
t2=ticks_to_millisecs(gettime());
if( (t2 - t1) > RECV_TIMEOUT) return -1;
}
usleep(1000);
}
return readtotal;
}
Re: LWP_CreateThread counterpart to stop thread execution?
Awesome! I'll be sure to give this a try but it will take some work rewriting to use non-blocking sockets. I just wish there was some better documentation for libogc so I could've found out about this myself a few days ago.
Who is online
Users browsing this forum: No registered users and 2 guests