106

I have a question regarding client socket on TCP/IP network. Let's say I use

try:

    comSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    comSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

except socket.error, msg:

    sys.stderr.write("[ERROR] %s\n" % msg[1])
    sys.exit(1)

try:
    comSocket.bind(('', 5555))

    comSocket.connect()

except socket.error, msg:

    sys.stderr.write("[ERROR] %s\n" % msg[1])

    sys.exit(2)

The socket created will be bound to port 5555. The problem is that after ending the connection

comSocket.shutdown(1)
comSocket.close()

Using wireshark, I see the socket closed with FIN,ACK and ACK from both sides, I can't use the port again. I get the following error:

[ERROR] Address already in use

I wonder how can I clear the port right away so that next time I still can use that same port.

comSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

setsockopt doesn't seem to be able to resolve the problem Thank you!

Braiam
  • 1
  • 11
  • 47
  • 78
Tu Hoang
  • 4,622
  • 13
  • 35
  • 48
  • 1
    Why does a client need a specific port? – AJ. Jun 17 '11 at 00:17
  • 3
    Because I have to put that into a production server, and in that server, all outgoing connections are blocked. I need to specify a specific port to the socket so that they can set up a rule on the firewalls that allows the connection to go through. – Tu Hoang Jun 17 '11 at 00:46
  • I suggest you copy & paste the actual code. What you wrote above has an obvious error that would prevent you from seeing the behavior you claim to have seen. This leaves readers with no idea what else you have neglected to tell us that might be causing your problem. – ʇsәɹoɈ Jun 17 '11 at 01:01
  • 3
    Your network administrators should understand that outbound traffic can be controlled by **destination** port. – AJ. Jun 17 '11 at 01:02
  • 7
    this has enough information. there's a 99% chance the problem is caused by the `TIME_WAIT` socket state, which the answer below has a solution for :) – lunixbochs Jun 17 '11 at 01:04
  • @ʇsәɹoɈ: What would be that **obvious error** that you mentioned? – Tu Hoang Jun 17 '11 at 01:10
  • 1
    what's your operating system? you can usually use netstat to see the state of a socket (look for the port number to identify the socket) – lunixbochs Jun 17 '11 at 01:10
  • tcp 0 0 98c5-9-134-71-1:freeciv mobile-166-132-02:2345 TIME_WAIT – Tu Hoang Jun 17 '11 at 01:14
  • Your network administrator should also understand that rules about local outbound ports add no security whatsoever and only inconvenience applications or make them infeasible. – user207421 Sep 13 '19 at 23:26
  • @TuHoang If the answer you accepted is correct, why didn't it work in your original code, which already contains it? Was that the real code? – user207421 Sep 13 '19 at 23:29

13 Answers13

148

Try using the SO_REUSEADDR socket option before binding the socket.

comSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

Edit: I see you're still having trouble with this. There is a case where SO_REUSEADDR won't work. If you try to bind a socket and reconnect to the same destination (with SO_REUSEADDR enabled), then TIME_WAIT will still be in effect. It will however allow you to connect to a different host:port.

A couple of solutions come to mind. You can either continue retrying until you can gain a connection again. Or if the client initiates the closing of the socket (not the server), then it should magically work.

Bryan
  • 6,529
  • 2
  • 29
  • 16
  • 1
    Still cannot reuse it. The time I have to wait before being able to reuse the same port is 1 minute 30 seconds :( – Tu Hoang Jun 17 '11 at 00:38
  • 6
    did you call `setsockopt` before `bind`? was the first socket created with `SO_REUSEADDR`, or just the failed one? the waiting socket must have `SO_REUSEADDR` set for this to work – lunixbochs Jun 17 '11 at 01:00
  • Yes, I did include comSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) but still doesn't work. – Tu Hoang Jun 17 '11 at 01:04
  • please paste your exact new code, and clarify whether you've had a successful socket open since you changed the code – lunixbochs Jun 17 '11 at 01:05
  • @lunixboschs: I posted the code on the original post since I cannot reply to my own thread. I still have to wait for around 1min30secs before I can actually reuse that port. – Tu Hoang Jun 17 '11 at 01:11
  • 1
    tcp 0 0 98c5-9-134-71-1:freeciv mobile-166-132-02:2345 TIME_WAIT – Tu Hoang Jun 17 '11 at 01:22
  • @Tanner: Updated my answer. I think that is what you are experiencing. – Bryan Jun 17 '11 at 01:35
  • Thank you :) But anyways, I just use a static port so that the Sys Admins create firewall rule for the connection. Since I only need to restart it once every 5 minutes so that wouldn't be an issue. – Tu Hoang Jun 17 '11 at 01:40
  • SO_REUSEADDR is for server sockets. Noobie is creating a client socket and should not be using bind() at all. – jcoffland Nov 13 '12 at 03:19
  • I think it is not your issue. Please see my answer below. – Rustem K Oct 17 '13 at 02:52
  • 2
    @jcoffland I agree he shouldn't be using `bind()`, but SO_REUSEADDR is for all sockets including not only TCP server sockets but also TCP client sockets and UDP sockets. Don't post misinformation here. – user207421 Sep 13 '19 at 23:28
  • Why is it that this answer propose a solution that according to the question explicitely does not work? And it's marked as correct?? – qwerty_so Dec 13 '20 at 10:49
  • 1
    @jcoffland that's incorrect. calling bind on outgoing socket is legal for port to port interaction - many well-known services do that. but there is indeed a problem with reusing port uf communication wasn't shutdown properly – Swift - Friday Pie Nov 10 '21 at 10:02
36

Here is the complete code that I've tested and absolutely does NOT give me a "address already in use" error. You can save this in a file and run the file from within the base directory of the HTML files you want to serve. Additionally, you could programmatically change directories prior to starting the server

import socket
import SimpleHTTPServer
import SocketServer
# import os # uncomment if you want to change directories within the program

PORT = 8000

# Absolutely essential!  This ensures that socket resuse is setup BEFORE
# it is bound.  Will avoid the TIME_WAIT issue

class MyTCPServer(SocketServer.TCPServer):
    def server_bind(self):
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind(self.server_address)

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler

httpd = MyTCPServer(("", PORT), Handler)

# os.chdir("/My/Webpages/Live/here.html")

httpd.serve_forever()

# httpd.shutdown() # If you want to programmatically shut off the server
user2543899
  • 361
  • 3
  • 2
22

According to this link

Actually, SO_REUSEADDR flag can lead to much greater consequences: SO_REUSADDR permits you to use a port that is stuck in TIME_WAIT, but you still can not use that port to establish a connection to the last place it connected to. What? Suppose I pick local port 1010, and connect to foobar.com port 300, and then close locally, leaving that port in TIME_WAIT. I can reuse local port 1010 right away to connect to anywhere except for foobar.com port 300.

However you can completely avoid TIME_WAIT state by ensuring that the remote end initiates the closure (close event). So the server can avoid problems by letting the client close first. The application protocol must be designed so that the client knows when to close. The server can safely close in response to an EOF from the client, however it will also need to set a timeout when it is expecting an EOF in case the client has left the network ungracefully. In many cases simply waiting a few seconds before the server closes will be adequate.

I also advice you to learn more about networking and network programming. You should now at least how tcp protocol works. The protocol is quite trivial and small and hence, may save you a lot of time in future.

With netstat command you can easily see which programs ( (program_name,pid) tuple) are binded to which ports and what is the socket current state: TIME_WAIT, CLOSING, FIN_WAIT and so on.

A really good explanation of linux network configurations can be found https://serverfault.com/questions/212093/how-to-reduce-number-of-sockets-in-time-wait.

Rustem K
  • 1,212
  • 11
  • 27
  • Also, you should be careful with your code. If your code still on development and some exceptions occured, the connection might be not closed properly especially from server side. – Rustem K Jan 07 '14 at 15:20
  • 9
    You should be fair and quote the sentences you copy & pasted from [Tom's](http://hea-www.harvard.edu/~fine/Tech/addrinuse.html) Network Guide. Please correct your answer. – HelloWorld Sep 22 '15 at 22:46
15

In case you face the problem using TCPServer or SimpleHTTPServer, override SocketServer.TCPServer.allow_reuse_address (python 2.7.x) or socketserver.TCPServer.allow_reuse_address (python 3.x) attribute

class MyServer(SocketServer.TCPServer):
    allow_reuse_address = True

server = MyServer((HOST, PORT), MyHandler)
server.serve_forever()
ErikR
  • 51,541
  • 9
  • 73
  • 124
Andrei
  • 10,918
  • 12
  • 76
  • 110
8

You need to set the allow_reuse_address before binding. Instead of the SimpleHTTPServer run this snippet:

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler, bind_and_activate=False)
httpd.allow_reuse_address = True
httpd.server_bind()
httpd.server_activate()
httpd.serve_forever()

This prevents the server from binding before we got a chance to set the flags.

Vukasin Toroman
  • 636
  • 7
  • 21
  • It seems much easier to subclass TCPServer and override the attribute, see [my answer](http://stackoverflow.com/questions/6380057/python-binding-socket-address-already-in-use/35363839#35363839) for example – Andrei Feb 12 '16 at 13:30
4

As Felipe Cruze mentioned, you must set the SO_REUSEADDR before binding. I found a solution on another site - solution on other site, reproduced below

The problem is that the SO_REUSEADDR socket option must be set before the address is bound to the socket. This can be done by subclassing ThreadingTCPServer and overriding the server_bind method as follows:

import SocketServer, socket

class MyThreadingTCPServer(SocketServer.ThreadingTCPServer):
    def server_bind(self):
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind(self.server_address)

Maurice Flanagan
  • 5,179
  • 3
  • 30
  • 37
3

I found another reason for this exception. When running the application from Spyder IDE (in my case it was Spyder3 on Raspbian) and the program terminated by ^C or an exception, the socket was still active:

sudo netstat -ap | grep 31416
tcp  0  0 0.0.0.0:31416  0.0.0.0:*    LISTEN      13210/python3

Running the program again found the "Address already in use"; the IDE seems to start the new 'run' as a separate process which finds the socket used by the previous 'run'.

socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

did NOT help.

Killing process 13210 helped. Starting the python script from command-line like

python3 <app-name>.py

always worked well when SO_REUSEADDR was set to true. The new Thonny IDE or Idle3 IDE did not have this problem.

peets
  • 393
  • 1
  • 4
  • 13
1

I know you've already accepted an answer but I believe the problem has to do with calling bind() on a client socket. This might be OK but bind() and shutdown() don't seem to play well together. Also, SO_REUSEADDR is generally used with listen sockets. i.e. on the server side.

You should be passing and ip/port to connect(). Like this:

comSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
comSocket.connect(('', 5555))

Don't call bind(), don't set SO_REUSEADDR.

jcoffland
  • 5,238
  • 38
  • 43
  • 2
    `bind()` and `shutdown()` have exactly nothing to do with each other, and the suggestion that 'they don't seem to play well together' is baseless. You have missed the part where he needs to use local port 5555. – user207421 Sep 13 '19 at 23:34
1

For me the better solution was the following. Since the initiative of closing the connection was done by the server, the setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) had no effect and the TIME_WAIT was avoiding a new connection on the same port with error:

[Errno 10048]: Address already in use. Only one usage of each socket address (protocol/IP address/port) is normally permitted 

I finally used the solution to let the OS choose the port itself, then another port is used if the precedent is still in TIME_WAIT.

I replaced:

self._socket.bind((guest, port))

with:

self._socket.bind((guest, 0))

As it was indicated in the python socket documentation of a tcp address:

If supplied, source_address must be a 2-tuple (host, port) for the socket to bind to as its source address before connecting. If host or port are ‘’ or 0 respectively the OS default behavior will be used.

1

another solution, in development environment of course, is killing process using it, for example

def serve():
    server = HTTPServer(('', PORT_NUMBER), BaseHTTPRequestHandler)
    print 'Started httpserver on port ' , PORT_NUMBER
    server.serve_forever()
try:
    serve()
except Exception, e:
    print "probably port is used. killing processes using given port %d, %s"%(PORT_NUMBER,e)
    os.system("xterm -e 'sudo fuser -kuv %d/tcp'" % PORT_NUMBER)
    serve()
    raise e
test30
  • 3,496
  • 34
  • 26
1

socket.socket() should run before socket.bind() and use REUSEADDR as said

Felipe Cruz
  • 940
  • 5
  • 14
  • he changed the content of the question: https://stackoverflow.com/revisions/6380057/4 - check the revisions before next time :) – Felipe Cruz Sep 14 '19 at 15:25
0

I think the best way is just to kill the process on that port, by typing in the terminal fuser -k [PORT NUMBER]/tcp, e.g. fuser -k 5001/tcp.

coldfix
  • 6,604
  • 3
  • 40
  • 50
Kiblawi_Rabee
  • 264
  • 1
  • 3
  • 5
0

I had the same problem and I couldn't find any other solution (reuse options didn't work) except restarting Raspberry Pi each time. Then I found a workaround;

comSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
comSocket.close()
comSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
comSocket.connect(('', 5555))

This means, define socket first, close it, then define again, so you can use the same port if it is stuck.

Semih
  • 33
  • 9
  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/30623520) – Aliaksandr S. Dec 20 '21 at 04:30