µTasker Forum
µTasker Forum => µTasker general => Topic started by: neil on December 18, 2008, 04:01:12 PM
-
Hi Mark,
Within TCP_EVENT_CLOSED event, I close the socket. But there are times when I would like to manually close the socket with the fnTCP_close(..); command, outwith the TCP_EVENT_CLOSED event.
I tried this, and straight away the TCP_EVENT_CLOSED event gets called, and a fnTCP_close(..) I placed there also gets called. And as soon as another attempt is made to connect to my server using the same socket, another TCP_EVENT_CLOSED, right before the connection is made.
Can I call the callback function with TCP_EVENT_CLOSED to close it (if so whats the best way)? Or do I set a flag when manually closing it so the fnTCP_close(..) after the TCP_EVENT_CLOS doesnt get called?
Regards
Neil
-
Hi Neil
Are you using this technique?
fnTCP_close(Socket);
return APP_REQUEST_CLOSE; // inform TCP that we have request a close
When manually closing from the callback it is important to return APP_REQUEST_CLOSE. If not, the TCP layer will believe that the other end of the connection is starting the close and thus continue with a passive close rather than an active close. During a passive close you would receive the event TCP_EVENT_CLOSED.
Could this explain what you are experiencing?
regards
Mark
-
Hi Mark,
No its when I have to close the socket outwith the callback routine.
Neil
-
Hi Neil
The events are called from the TCP layer and will always be called when certain things occur.
I think that you will indeed need to inform your listener if it should not react to certain events which are caused by other actions which you are controlling.
Note that there are two events which occur when closing a connection:
TCP_EVENT_CLOSE (on an idle connection timeout and when the other end requests a close)
and
TCP_EVENT_CLOSED (when the TCP state leaves the TCP_STATE_TIME_WAIT, which can be 2 minutes after a connection has been closed or when the socket f freed since it needs to be used again by a new connection, or a successful passive close).
Check whether the use of both may help to distinguish certain cases.
Regards
Mark
-
Hi mark,
1. Is there a way to inform callback routine that I have closed the socket, or does the callback automatically get called because of the fnTCP_close(Socket) command?
2. do I do the following ONLY if not within events TCP_EVENT_CLOSED and TCP_EVENT_ABORT :
fnTCP_close(Socket);
return APP_REQUEST_CLOSE;
3. If my windows application closes the socket, do I have to place fnTCP_close(Socket) in event TCP_EVENT_CLOSED and TCP_EVENT_ABORT, then return APP_ACCEPT ?
Neil
-
Hi Neil
1) Generally you shouldn't have to inform the callback about the socket being closed. It will receive an TCP_EVENT_CLOSE event when the close process is completed. It may also receive TCP_EVENT_ABORT if the connection is closed by a TCP RST reception.
2) The following is only performed from within the TCP_EVENT_ACK, TCP_EVENT_PARTIAL_ACK or TCP_EVENT_DATA callback events
fnTCP_close(Socket); // terminate the connection
return APP_REQUEST_CLOSE;
3) Yes, always return APP_ACCEPT to TCP_EVENT_CLOSED and TCP_EVENT_ABORT events. Note that a server will no longer be in the listening state after a close and you need to call fnTCP_Listen() from within this event to set it back to listening state if you want it to accept further connections.
Regards
Mark
-
Hi Mark,
If the tcp connection is lost, improperly (perhaps cable pulled out), my application has a timer, and will call fnTCP_close(Socket). As the communication for closing the socket between the board and my windows application wasnt in the normal way, will the callback routine be called at all?
Neil
-
Hi Neil
If one side of a TCP connection is removed (eg. cable pulled or PC turned off, etc) the TCP connection remains open. This is normal and not a problem.
Sometimes there will be an activity timer automatically closing such a connection after a certain period of time. Other possibilities involve a monitor at the application level, which is what you have.
When the connection is closed (due to a connection timeout or other command), the TCP layer will try to perform the normal close sequence. Since the other end of the connection is not available, the normal sequence will not lead to a normal close but will try a few times and finally declare a failure. This results in a reset of the connection and the event TCP_EVENT_ABORT being received. For this reason the abort case is very similar to the TCP_EVENT_CLOSED case since it is confirming that the connection has been terminated - although not from a standard FIN procedure.
You should thus always receive an event and be able to determine that a connection has terminated.
Regards
Mark
-
Hello mark,
I open TCP connection then get TCP_ABORT event as nobody is connected...
I try 3 different servers then I wnat to close the socket and try again.
I use the folowing code, on which I put a tGIP_TCP_socket variable for test purpose.
In fact my problem is that this code dont free the TCP I wanted to closed and in fact open a new connection as eack attempt.
The fnTCP_close function return the value 07, which I don't understand.. Can you help ?
case GIP_OPEN_REQUESTED:
tGIP_TCP_socket = fnTCP_close(GIP_TCP_socket);
if ((GIP_TCP_socket = fnGetTCP_Socket(TOS_MINIMISE_DELAY, TCP_NO_TIMEOUT, fnGIPListener)) >= 0) {
ucGIP_state = GIP_STATE_OPENED;
fnDebugMsg("GIPxchg MOUNT:");
fnDebugHex(GIP_TCP_socket ,1);
fnDebugMsg("\r\n");
} // if
else
fnDebugMsg("GIPxchg NO_MOUNT\r\n");
uTaskerStateChange(OWN_TASK, UTASKER_ACTIVATE);
break;
-
Hi,
In fact I made a mistake and the return value is 2 : TCP_STATE_CLOSED
But fnGetTCP_Socket test for TCP_STATE_FREE to affect a new socket.
How can I free a socket ?
-
Sorry,
Simply using fnReleaseTCP_Socket()
Everything is OK now...