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
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
When accepting a connection, you will get a new connection. But that shouldn't stop the server from listening on 300 for new connections.
A web server listening on port 80 will not stop listening for new connections on port 80 even when it accepts a connection for service.
But the code in the server must handle both the listen on the original socket, and wait for data to arrive (or send out data) on the new connection.
Of course many servers do limit the total number of concurrent connections. So they may do an accept + close if they already have the max number of connects.
Another thing is that most stacks allows the queue limit for the socket to be controlled - how many new connections that may be queued in wait for being accepted.
thanks a lot Per Westermark
then I should listen to port 300 forever and each connection should be changed to another port to let port 300 free for listening.
so my policy was some how true and some how false, wasn't it?
I've changed port but never listened to port 300.
Do you have any solution to detect the port closure faster?
because I'm not that much free to send packet for closure detection.
another solution that I think it's not bad is when another connection want's to connect on port 300 I try to close previous port because at the same time there should be one connection with my device. what's your idea about it?
thanks in advance
"then I should listen to port 300 forever and each connection should be changed to another port to let port 300 free for listening."
That is NOT necessary. You can listen on a port, maintain a session accepted on it and carry on listening for other connections on that same port.
"Do you have any solution to detect the port closure faster?"
The Keil libraries detect port closure very quickly. I have used their basic TCP session example on three different processors - I have not taken measurements of the delay, but it appears to be 'almost instantaneous'. If you're not seeing a quick closure then it implies that you have something wrong.
As I wrote before: So have you gone back to the basics and tried one of the Keil demo programs?
What result do you get from that?
You also state:
"...because at the same time there should be one connection with my device.
That is easy to detect and is indicated within the Keil example.
I have used their basic TCP session example on three different processors - I have not taken measurements of the delay, but it appears to be 'almost instantaneous'.
Did you test DP83848 with AT91sam7x?
if yes, do you have EMAC configuration for DP83848. because I think EMAC configuration is the cause of such problem.
thank you
"Did you test DP83848 with AT91sam7x?"
No.
"because I think EMAC configuration is the cause of such problem."
Why? The TCP closure is just another TCP packet (with the FIN flag set). If you had a problem with EMAC, then surely other packets would be problematic. If you are seeing other faults, then you really need to get those fixed before worrying about closure.
thanks every body
my problem has been resolved.
I did what ever you said and add tcp_abort() to TCP_EVT_ABORT and TCP_EVT_CLOSE
and after that every thing was OK.
Microcontroller could detect the closure of port very fast because microcontroller would send a packet with zero byte of length as a keep alive method 10sec after the latest packet which is received to detect whether connection is open and if result be false it'll close and abort that socket.
may it will be useful for another else, because I've faced with it:
for ethernet we have such a thing:
__task void tcp_task (void) { while (1) { main_TcpNet(); dhcp_check (); //here is the place of keep alive os_tsk_pass(); } }
and I tried to add keep alive here because if the keep alive be separated form this loop maybe TCP get crashed.
thanks a lot
good luck
"...add tcp_abort() to TCP_EVT_ABORT and TCP_EVT_CLOSE"
Is not necessary (and I think is just plain wrong, since there are limitations to the calls you can make to TCPnet from within the callback function).
"and I tried to add keep alive here because if the keep alive be separated form this loop maybe TCP get crashed."
You do not need to add explicit code to transmit the 'keep alive' - TCPnet (if configured to do so) will do it automatically. Besides which, as far as I am aware, the keep alive cannot be created by simply sending a zero byte TCP block.
I think you should spend more time reading the manual(s).
with that method which I said, it is fine. every thing is OK.
and without tcp_abort the system can not connect to new port.(system will set to listening state but I've got timeout error if I don't do such a thing)
and about keep alive with zero length packet is not bad because I could recognize closure of TCP port. and it is just 10 seconds after the latest received packet because my system will send at least one packet per each second.
Is there any wrong thing which is mentionable?
because the system is under test and I need to make it reliable enough.
"Is there any wrong thing which is mentionable?"
It seems you must be using a different TCPnet to the one I recognise.
"and about keep alive with zero length packet is not bad because I could recognize closure of TCP port. and it is just 10 seconds after the latest received packet because my system will send at least one packet per each second."
If you're going to send at least one packet per second, why do you need a keep alive packet each 10 seconds?
"...I need to make it reliable enough."
You better do some serious studying.