Hi
I'm using AT91sam7x512 with DP83848 for Ethernet connection and in my project device is set as host, and every thing is OK except TCP closed detection.
I've used tcp_get_state() to determine which state my device is. but it's really unreliable and maybe after 10 minute I could detect that the connection was lost and sometimes never I could.
my cable connected to the PC through Ethernet switch and I've set timeout to 120.
in configuration of DP83848 I've used auto negotiation mode to connect and there's not any difference between auto neg. and fixed mode(100BT or something else)
Does anybody have suggestion?
if you could help, I'd appreciate you.
thanks
Are you talking about a correct TCP closure or a disconnection of a cable?
If you're talking about TCP closure, then the stack provides an event to tell you of it.
If you're talking about trying to detect when the cable has been disconnected (or cut), then the TCP protocol stack will not directly tell you of the event.
For example when an application connect to this device as a client if I try to close the connection in PC or close that application, my device doesn't show me anything. in the other worlds running and closing application in PC for two times will cause such problem.
these are the same in unplugging the cable or closing the connection by software.
anyway when the client be disconnected, the server's port is open and never be closed for a long while or forever.
No, it is not the same thing to close a TCP connection and to disconnect a network cable.
You just can't see a disconnected cable without trying to send data and notice the transfer failure.
So a TCP connection with KEEP_ALIVE will notice a disconnected cable, but a connection without may think it is connected days later.
One side actually closing a connection on the other hand means that the two TCP/IP stacks will talk with each other and make sure that both sides knows that the connection is getting closed.
If you connect using telnet to another computer somewhere, and the connection is unreliable, you can see that if you use KEEP_CONNECT, and go to bed, the connection will probably have disconnected in the morning. If you didn't use KEEP_CONNECT, it really doesn't matter if there is a link between the two machines until you try to press a key and your side notices that it fails to communicate.
I swear that there is no any difference between unplugging and closing port by software in my device. both of them take me a long time to detect.
I couldn't get you about KEEP_ALIVE, what is it?
I've used RL-ARM and I have just tcp_get_state to recognize the TCP status.
here per each received data packet in my device, I try to send a packet to client side, so there is no way to send a packet to detect TCP closure without any received packet.
would you please tell me more about this matter?
if here is an optimized and standard way to detect such a thing maybe I'd change my implementation policy.
thanks in advance
I swear that there is no any difference between unplugging and closing port by software in my device
NNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOO
1. Listen to what you are told 2. Read about TCP/IP design philosophy and you will understand. 3. No near to swear here.
"I've used RL-ARM and I have just tcp_get_state to recognize the TCP status."
Hopefully, you've implemented a callback function as per the RL-ARM documentation - The one whose address is passed to the function tcp_get_socket.
Within that, you check for the event TCP_EVT_CLOSE to detect when the socket has been properly terminated.
For you, the KEEP_ALIVE might be worth reading about. Typically, this is a TCP packet that is sent periodically and automatically by the TCP stack. The other side of the session would be expected to send an acknowledgement for the packet - So if no acknowledgement is received (within a reasonable timeframe), the connection is terminated. The frequency of the KEEP_ALIVE is reasonably long (typically something like 1-10 minutes) and the timeout mighty be of a similar time - So the detection of a missing cable should not be expected to be immediate.
I said my device behavior is in this way(they are the same just because of time to detect). I know there is difference between unplug and colsing port by software.
and I've used all you said (callback and other else)
How can I check TCP stack?
thank you
"and I've used all you said (callback and other else)"
So do you get the event to tell you of the TCP session closure?
"How can I check TCP stack?"
For what? The callback tells you when the closure is detected.
Oh my GOD, please help me
I said I've used all routines same as callback, and with this situation I have such a problem.
I don't know could you get me what I said: I've written callback routine and when I closed the port connection after a long while the condition of TCP_EVT_CLOSE will be true and the microcontroller could detect the closure of connection(and sometimes never), same as below which is on uVision help:
#include <rtl.h> U8 tcp_soc; U16 tcp_callback (U8 soc, U8 event, U8 *ptr, U16 par) { /* This function is called on TCP event */ .. switch (event) { case TCP_EVT_CONREQ: /* Remote host is trying to connect to our TCP socket. */ /* 'ptr' points to Remote IP, 'par' holds the remote port. */ .. /* Return 1 to accept connection, or 0 to reject connection */ return (1); case TCP_EVT_ABORT: /* Connection was aborted */ .. break; case TCP_EVT_CONNECT: /* Socket is connected to remote peer. */ .. break; case TCP_EVT_CLOSE: /* Connection has been closed */ .. break; case TCP_EVT_ACK: /* Our sent data has been acknowledged by remote peer */ .. break; case TCP_EVT_DATA: /* TCP data frame has been received, 'ptr' points to data */ /* Data length is 'par' bytes */ .. break; } return (0); } void main (void) { init (); /* Initialize the TcpNet */ init_TcpNet (); tcp_soc = tcp_get_socket (TCP_TYPE_SERVER, 0, 30, tcp_callback); if (tcp_soc != 0) { /* Start listening on TCP port 80 */ tcp_listen (tcp_soc, 80); } while (1); /* Run main TcpNet 'thread' */ main_TcpNet (); .. } }
after closure there is no any event to recognition or it's too late.
So have you gone back to the basics and tried one of the Keil demo programs?
What result do you get from that?
Oh my GOD please tell what your problem is.
You write: "I don't know could you get me what I said: I've written callback routine and when I closed the port connection after a long while the condition of TCP_EVT_CLOSE will be true and the microcontroller could detect the closure of connection(and sometimes never), same as below which is on uVision help:"
Yes, if you close the socket after a long time, the TCP stack should notice a close.
But that is expected. But since that isn't a problem, what really is your problem? What does _not_ happen as expected?
Don't you get to know about the close if you close the socket after a short time?
One of the sides must close the connection - or a transfer must fail - for you to get a notification that the socket has closed.
And you have not given us an example where the stack should have notified about a close, but haven't.
SO please don't "Oh my GOD" us. Concentrate of describing a situation where you see a difference between what is expected and what really happens.
The quality of the help you get depends directly on the quality of your posts.
I used that example and server is listening to port 300 (for example) and the client connect to server through this port and both will change the port to another port to transferring data. till here there is no any problem. but when the connection be closed by both ways (unplugging or closing the program on PC) my device which is the server, couldn't detect the closure (sometimes for a long time and sometimes never could detect) and if I try to run the program on PC (client side) because the client wants to connect to port 300 and server isn't listening on port 300 they couldn't connect to each other.
there is not any difference between unplugging and closing port by client, and it's not depend on how long they were connected to each other, there is a big gap between closure and detection.
and I think it's not usual, because for PC if we unplug the cable or close the connection we could detect it very fast. besides it's not usual to say I'll waiting to detect the closure and after that I try to run the program on PC.(I disabled multi port connection at the same time)
another thing: I'm using AT91sam7x and I wrote the EMAC configuration for DP83848 by myself according to LPC23xx code bundle. Are lpc23xx with DP83848 in this way?
I hope to be clear
couldn't detect the closure (sometimes for a long time
Are you being deliberately vague, or did it really still not occur to you that you need to replace such meaningless quantities like "a long time" by some hard facts?
because the client wants to connect to port 300 and server isn't listening on port 300 they couldn't connect to each other.
Sounds like a pretty blatant design error in your server program, to me. Why stop listening on your principal server port just because you think you have an ongoing transaction on the other one? What's that changing-port business even going to achieve, if you don't keep the primary port open at all times?
The NIC on the PC will detect link lost if the local network cable is removed - or you remove power to the switch or whatever is sitting on the other side.
But link loss is only detected when the break in the network happens in the first step - and you can see it by the network connector link LED turning off.
But that is a completely separate issue from the normal "close" issue - when something happens somewhere between computer A and computer B that makes it impossible to transfer any packets, then neither computer A nor computer B will know that the connection is dead unless they send any data so they may notice the transfer failure.
Since a link loss is not the same as a close of a connect, you normally have other ways to try to detect it, even if the network stack _may_ decide to automatically close all connections. And a device using DHCP may find that it no longer have any IP number on the interface.
A PC is also sensitive to loss of connection or programs being forcibly killed. If you run bittorrent (that is a protocol using huge amounts of short connects) and after a couple of hours looks in your firewall, you will find that the firewall may have a large number of dead connections. But the firewall doesn't know they are dead because silence can't be detected. Only lack of answers can be detecetd. So
KEEP_ALIVE is a way that the network stack can be instructed to send data itself, to monitor that there is a connection with the other side. KEEP_ALIVE or manual transfer of data are the only ways that can handle the situation where the network dies somewhere in between with the potential exception of a link loss directly on the NIC.
Next thing - as already noted - is why you don't always keep your server listening on the server port. Are you aware, by the way, that a TCP/IP stack normally locks a port for reuse for a while after it has been closed? Google for SO_REUSEADDR for information about this.
thanks GOD
I'm some how satisfied due to Mr Per Westermark notices.
when server is listening to for example port 300 and client be connected to port 300 both of them will close that port and will connect to each other for example on port 900. and there is not any port 300 which is listened by server. Is it wrong? why?
any way, as I undrestand I should send a packet periodically to detect the connection closure, isn't it?
thanks guys