µTasker Forum
µTasker Forum => NXPTM LPC2XXX and LPC17XX => Topic started by: er.saurabh19 on February 12, 2010, 08:06:27 AM
-
Dear Mark and all other uTasker users...
I am facing a strange problem... I am observing many TCP connection aborts...
when connecting my device with PC TCP client.
My totology is as below...
PC Client (TCP... Port 502)
|
|
-----------------------------------------------------------------
| | |
Device no 1 Device no 2 Device no n
All devices have the same firmware which have TCP listener on their port 502 (modbus)
What I observed some devices (not all)... hangs after some time... and when I check log
it shows several conenction aborts.. while others who still works dont shows the connection
aborts.
TCP session is as below at PC side:
PC TCP client connects to X device (make TCP Connection) ... take data in close the connection.
and again come to the device after some 3-8 seconds to take new data....
Now I suspect my TCP listner code... which we referred from HTTP listener code from
uTasker's HTTP module.....
May some corrections are needed ... please guide me
Listener code as below..........
/************************************************************************
TCP listener (Max socket created is 3, from the pool).. same declared... in max user socket
macro..
*************************************************************************/
static int fnTestListener(USOCKET Socket, unsigned char ucEvent, unsigned char *ucIp_Data, unsigned short usPortLen)
{
int n,i,Ret=0;
unsigned char TP[30];
TCP_MESSAGE test_message;
switch (ucEvent)
{
case TCP_EVENT_CONREQ:
if(ucEvent==TCP_EVENT_CONREQ)
{
fnDebugMsg("\r\n---> Req for Conn.."); // debugging info
sprintf(TP,"[SockID=%d ] ###",Socket);
fnDebugMsg(TP);
ConReq++;
}
case TCP_EVENT_CONNECTED:
if(ucEvent==TCP_EVENT_CONNECTED)
{
fnDebugMsg("\r\n---> Socket Connected.."); // debugging info
sprintf(TP,"[SockID=%d] ###",Socket);
fnDebugMsg(TP);
TotCon++;
Con++;
}
case TCP_EVENT_ACK:
sprintf(TP,"[ucEvent=%d] ###",ucEvent); // debugging info
fnDebugMsg(TP);
EveAck++;
break;
case TCP_EVENT_ARP_RESOLUTION_FAILED:
sprintf(TP,"[ucEvent=%d] ###",ucEvent);
fnDebugMsg(TP);
ARP_Fail++;
break;
case TCP_EVENT_PARTIAL_ACK:
Ret=1;
Par_Ack++;
fnDebugMsg("\r\n->Pack");
sprintf(TP,"[SID=%d]##",Socket); // debugging info
fnDebugMsg(TP);
//return HANDLING_PARTICAL_ACK;
return APP_REQUEST_CLOSE; // This is also suspected !!
break;
case TCP_EVENT_REGENERATE:
Regn++;
Ret=2;
if(ucEvent==TCP_EVENT_REGENERATE)
{
fnDebugMsg("\r\n--->REGEN");
sprintf(TP,"[SID=%d]##",Socket);
fnDebugMsg(TP);
}
return APP_SENT_DATA; // May this is workaround , and suspected... !!
break;
case TCP_EVENT_DATA:
Rec++;
// sprintf(TP,"[ucEvent=%d] ###",ucEvent);
// fnDebugMsg(TP);
if((MenuFlag==0))
{
TCP_ON=1; //Notify Firmware that TCP meg arrive , and in process
DecodeMsg(ucIp_Data); // Decode msg arrived for validity
fnDebugMsg("\nucIp_Data =");
for(i=0;i<20;i++) // Disply Msg
{
sprintf(TPgu,"[%u = %x]",i,ucIp_Data);
fnDebugMsg(TPgu);
}
fnDebugMsg("\n");
if(ValidFrame==1) // Reply Data only if modbus query is valid
{
for(i=0;i<TCPd.ResponceLength;i++)
{
if(i<300) // Copy Modbus reply data in ti ucTCP msg buffer
{
test_message.ucTCP_Message=TCPd.RS;
}
}
// Send Data
if(fnSendTCP(Socket, (unsigned char *)&test_message.tTCP_Header, TCPd.ResponceLength, TCP_FLAG_PUSH) > 0)
{
return APP_SENT_DATA;
}
}
else
{
fnDebugMsg("\n@ Not valid Frame..@");
//return APP_SENT_DATA; // May this is not correct
}
TCP_ON=0;
}
else
{
//return APP_SENT_DATA; // May this is not correct
}
break;
case TCP_EVENT_ABORT:
if(ucEvent==TCP_EVENT_ABORT)
{
TotAbort++;
Con--;
fnDebugMsg("\r\n---> Aborted.."); // debugging info
sprintf(TP,"[SockID=%d] ###",Socket);
fnDebugMsg(TP);
}
case TCP_EVENT_CLOSED:
if(ucEvent==TCP_EVENT_CLOSED)
{
TotClose++;
Con--;
fnDebugMsg("\r\n---> CLOSED.."); // debugging info
sprintf(TP,"[SockID=%d] ###",Socket);
fnDebugMsg(TP);
}
fnTCP_Listen(Socket, usTestPort, 0); // go back to listening state on next port number
// I dont know weather this is correct ... and
// not leading to many partial opened connections
break;
}
return APP_ACCEPT; // This is also suspected !!! why I return this as default
} ???
-
Hi
Looking at the listener I have following comments:
1) It is correct to generally return APP_ACCEPT. In any other cases a different return can be specifically returned.
2) The event TCP_EVENT_ACK is generally used as a signal to allow further data to be sent - no data should be sent before an ack to previous data has been received since this will cause TCP counter errors to occur - this can lead to the failure of a connection. This is true for simple, non-buffered TCP sockets, whereby these are very suitable for MODBUS/TCP use since there is never more than one outstanding MODBUS queries at a time.
3) TCP_EVENT_ARP_RESOLUTION_FAILED is usually handled in the same way as TCP_EVENT_REGENERATE and in TCP_EVENT_REGENERATE it is normal to repeat the last TCP frame (which must also be saved until it has been acked). It is not allowed to return APP_SENT_DATA when no data has really been sent otherwise the TCP layer will not acknowledge data reception and so the link will fail.
4) TCP_EVENT_PARTIAL_ACK will never occur when working with a simple TCP socket - if it does it means that data is being sent without waiting for a previous frame to be acked.
5) Returning APP_REQUEST_CLOSE will cause the connection to be closed - only return it when you want this to happen.
6)
if(fnSendTCP(Socket, (unsigned char *)&test_message.tTCP_Header, TCPd.ResponceLength, TCP_FLAG_PUSH) > 0)
{
return APP_SENT_DATA;
}
This is correct use. The APP_SENT_DATA should never be returned in any other case though.
7)
fnTCP_Listen(Socket, usTestPort, 0);
This is used by a server after a connection is closed to set the server back to listening state. It is correct in the case of a server.
Regards
Mark
Further notes:
- There is also a uTasker MODBUS package which may be suitable for a project requiring MODBUS support: http://www.utasker.com/modbus.html
- The use of TCP also also explained in the the following thread: http://www.utasker.com/forum/index.php?topic=25.0
- More details to individual TCP calls can be found in the TCP.c section of the code documentation: http://www.utasker.com/docs/Code.html
-
Just a wild guess, are you sure your MAC addresses are unique? I had some peculiar problems when I forget to program separate MAC addresses :)