Sign in to follow this  
ProPuke

tcp consecutive connect() timeout

Recommended Posts

I'm having problems reconnecting nonblocking tcp sockets bound to the same source port... (winsock using standard Berkeley calls) sorry I'll backup & try & make more sense: When the socket is first created I allow winsock so assign me a free port I then save the assigned port & set the socket into nonblocking mode The first connect() on this socket always succeeds After the connection succeeds & is ended (or fails) the socket is closed Another socket is then immediately created in its place & assigned the same port & attempts to connect() to the same host (& target port) again Now sometimes this works fine & the sockets establish their connections, receive the allotted packets, disconnect, then repeat But other times the source port seems to become invalidated after the first connect() & all later socket connects bound to the same source port will fail with an eventual connect() timeout This socket invalidation only seems to occour directly after the first connect 99% of the time (it does occasionally occour after several, but this is highly rare) All winsock socket calls are fully error checked & it reports no problem whatsoever on rebinding of the same port, nor should it I believe The server is in a blocking accept loop & receives no input whatsoever while the client slowly times out with its connect() call
If anyone has experienced these symptoms before or feels they could shed some light on this it would be fully appreciated oh btw: all sockets (client & server) are currently being shutdown() with SD_BOTH prior to closesocket() & are being closed serverside [Edited by - ProPuke on June 24, 2005 3:58:02 PM]

Share this post


Link to post
Share on other sites
Why do you want the same source port? Usually the local port you use for outgoing connections is irrelevant.

You could try setsockopt with SO_REUSEPORT but I don't think Windows supports it. I don't even think it's entirely relevant here, but it's worth a go.

You might also try running netstat to see what state the port is in when you're doing this. It may shed some light on the issue.

Share this post


Link to post
Share on other sites
My app uses the port as a form of identifaction

I've tried enabling SO_REUSEPORT, but to no avail. You see the port's not actually in use. If it were then it would report an error upon bind

The ports in constant TIME_WAIT status :/


Well really I was just posting this in the hope that soembody else had had the same problem, I guess not

Thanks for taking the time to reply anyways Kylotan

Share this post


Link to post
Share on other sites
The option is called SO_REUSEADDR, and you must have set it on the socket that goes away to allow a new socket to bind to the same port before the TIME_WAIT state is exited. Typically, you'll stay in TIME_WAIT for more than a minute; this behavior is there to be able to respond to possible stray/late packets intended for the original connection.

So:
1) enable SO_REUSEADDR
2) take a coffee break, to avoid previous binds without SO_REUSEADDS to time out
3) from now on, you should be able to re-bind as often as you want (assuming the original listener is closed)

Share this post


Link to post
Share on other sites
Sorry I also meant SO_REUSEADDR
& sadly no, it doesn't solve the current situation
There doesn't appear to be any problem with the binding, nor with any other function calls
They all issue perfectly
It's just that the nonblocking connect() eventually just times out after the first connection is closed

Thanks anyway hplus0603,
I think I'll just go rhythmically beat my head against this wall :/

Share this post


Link to post
Share on other sites
The server is in a blocking accept loop, yes
But while the clients connect() is timing out the server is still sitting @ accept with no word from any new connections

extra:
just to expand on that - I can start extra clients while the first one is timing out & they can still connect fine (well they're guarenteed to connect fine the first time anyways, later ones may fail)
I can also restart the server, but as long the client continues to try to use the same sourceport it will always timeout

[Edited by - ProPuke on June 25, 2005 11:08:49 AM]

Share this post


Link to post
Share on other sites
No socket option is going to help as long as the port is in TIME_WAIT.

The TCP protocol prevents the same (ipaddress,port -> ipaddress, port) pairs from being re-used for the TIME_WAIT period.

In other words, if the port is in TIME_WAIT, you cannot use it to connect to the same REMOTE address+port.

You could connect to a different port on the server, but I don't suppose that's what you want.

You have two alternatives:

1. Close the connection abortively. Use the SO_LINGER socket option with a timeout of 0.

2. Don't use the same port to make another connection.

2 is obviously better. it's not that much work to keep a port number and increment it each time you bind().

Share this post


Link to post
Share on other sites
thanks nevernomore

dang I remember looking @ the shutdown SO_LINGER option too, damn I should of tryed it
But really thinking about it now it probally wouldn't of been the wisest of choices anyway
TCP connection sockets are best left alone once they're done I think (they kinda scare me)
Yeah I just changed port between each tcp master server ping, problem is the port used when doing that was used to mark what udp port the client was also listening on, so I had to introduce port shuffling to the udp clients.. anyways I'm rambling

It's done now & the project is going forward again
Thanks for taking the time everyone

I've just one question though.. Why is it that winsock allows you to bind to ports that are still listening? I mean they're useless to work with aren't they?
What would be the point in allowing new sockets to bind to them?

Well cheers guys ;]

Share this post


Link to post
Share on other sites
If you set the SO_REUSEADDR option, you said you wanted to use the same port. You can't go about blaming winsock for doing what you asked it to do :)

The assumption there is that you want to connect to a different IP address/port.

Share this post


Link to post
Share on other sites
SO_REUSEADDR is specifically for use where you know that you'll kill a process (or somehow kill a listening socket), and don't want to wait 2 minutes before you can bring up the service and start listening again.

It won't help if you're trying to bind to a socket that's already currently bound. It also won't help if you try to bind on an outgoing socket -- which you should pretty much never do, unless strictly necessary to make it easier to circumnavigate some firewalls.

Share this post


Link to post
Share on other sites
Minor quibble, but SO_REUSEADDR is not exclusively designed for the purpose you describe. It is used in the general case of needing to bind() to the same port. There can be a variety of reasons for doing so.
For example, FTP servers bind multiple sockets to port 20 when making data connections back to clients. Since they talk to different clients (hence different IP addresses) over each socket, it works.

I would also disagree with using SO_REUSEADDR in the manner you indicate, but that's even more off-topic :-)


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this