I'm coding a network utility to share the mouse and keyboard between two Amiga OS4 machines.
As such I need to send messages back and forth between the machines in a timely fashion and in fact it's working rather well *most* of the time, but I'm seeing two issues.
1. If I have to interupt and restart the server, the I see that the listen socket hangs arround arround for more than a minute after I closed it down. Is this normal? It means the server can't be restarted, as it can't bind to the port number. This is largely only a problem when testing as when running for real the server would rarely need a restart, but I want to be sure that I'm not missing something in the shutdown procedure. I'm closing the socket with ISocket->CloseSocket() and ofcourse I close bsdsocket.library at prpgram exit. (Note this is not an inetd style server so it';s not the inted thing holding the scocket open).
2. This is the more complex one I think:
90% or more of the time the return trip of the server sending a command to and getting a response from the client takes at most 50ms most oftem much less. This allows quite smooth operation of the mouse on the remote (client) machine. Every now and again though I'm getting amassive delay of more than 1300 ms this causes quite a stutter in the mouse as you might imagine.
I'm trying work out why this is happening, and have added lots of timing debug, it seems to me to be that the delay is at the network level.
My packets of info are short eg "RAWMOUSE %hu %hu %hd %hd" but it seems occasionaly the client has to wait up a second to recieve the packet (and this is across the LAN ).
Some simplified code:
Server SendMsg() code:
struct TimeVal tv;
tv.Seconds = 2;
tv.Microseconds = 0;
int n = 0;
if((n = ISocket->WaitSelect(FD_SETSIZE,NULL,&writefds,NULL,&tv,NULL)) != -1)
{
if(n > 0)
{
if( ISocket->send(sock,(APTR)msg,strlen(msg) + 1,0) == -1)
{
DropClient(server,sock);
return FALSE;
}
}
else
{
/* Timeout increment dropped packets */
printf("Send Timeout\n");
DropClient(server, sock);
return FALSE;
}
}
else
{
printf("WaitSelect error %s %d\n",__FUNCTION__,__LINE__);
return FALSE;
}
/* autodoc says not to assume timevalue unchnaged so reset */
tv.Seconds = 2;
tv.Microseconds = 0;
if((n = ISocket->WaitSelect(FD_SETSIZE,&readfds,NULL,NULL,&tv,NULL)) != -1)
{
if(n > 0)
{
TEXT buffer[512];
if( ISocket->recv(sock,buffer,sizeof(buffer),0) == -1)
{
DropClient(server,sock);
return FALSE;
}
enum Protocols ID = IdentifyProtocol(buffer);
switch(ID)
{
...
...
...
Code Handleing response here
...
...
...
}
}
else
{
/* Timeout increment dropped packets */
printf("Receive Timeout respoe to %s\n",msg);
DropClient(server,sock);
return FALSE;
}
}
else
{
printf("WaitSelect error %s %d\n",__FUNCTION__,__LINE__);
return FALSE;
}
return TRUE;
}
Client loop:
while(alive)
{
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(sock,&readfds);
struct TimeVal tv;
tv.Seconds = 4;
tv.Microseconds = 0;
int n = 0;
if((n = ISocket->WaitSelect(1,&readfds,NULL,NULL,&tv,NULL)) != -1)
{
if(n > 0)
{
int len;
if((len = ISocket->recv(sock,buffer,sizeof(buffer) -1,0)) > 0)
{
buffer[len] = 0;
enum Protocols ID = IdentifyProtocol(buffer);
switch(ID)
{
case RAWKEY:
{
SendResponse(sock,(APTR)RECEIVED_MSG,strlen(RECEIVED_MSG) + 1);
/* Do stuff include input.device IO */
break
}
...
...
...
...
Handle Other stuff
...
...
...
}
}
else
{
/*Could be Socket error or shutdown we don't care */
printf("sock error %ld\n",ISocket->Errno());
alive = 0;
reconnect = 1;
}
}
else
{
/* Timeout */
printf("Connection time out\n");
alive = 0;
reconnect = 1;
}
}
Where SendResponse() in the client is thin wrapper for ISocket->send() lik so:
static VOID SendResponse(int sock, APTR response, size_t length)
{
if(sendbye)
{
TEXT buffer[24];
sprintf(buffer,BYECLIENT_MSG,name?name:"");
ISocket->send(sock,buffer,strlen(buffer) + 1,0);
alive = FALSE;
sendbye = 0;
}
else
{
ISocket->send(sock,response,length,0);
}
}
From my timing tests (with alot of unshown dbeug printouts inserted into the above code, it seems the delay occurs in Server at the second Wait slect and in the client at the first, which suggest the dealy is after te send() in the server, but that function returns promptly (typically 1 ms or less)
Timeing was done with ReadEClock calls.
I can't see any reason to get these stalls in the data flow, perhaps I'm not setting some options that would help? I'm just the using sockets 'as they come'.