getting socket.bind() exception, but no actual error

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Clarence Gardner

    getting socket.bind() exception, but no actual error

    I've got a problem that I don't see how to program around. A socket server
    that was running fine, today started getting an exception from the bind()
    call (errno 22, Invalid argument) and yet the bind had actually worked.

    This is apparent from this code: it prints the error message, but then
    breaks out of the loop and the listen() and accept() calls work normally.

    How can one handle a function that is both working and raising an
    exception?

    sockobj=socket( AF_INET,SOCK_ST REAM)
    while True:
    try:
    sockobj.bind((' ',4321))
    except socketerror,e:
    print e
    if str(e).find('in use') == -1:
    break
    print '.'
    time.sleep(1)
    sockobj.listen( 5)
  • Steve Holden

    #2
    Re: getting socket.bind() exception, but no actual error

    Clarence Gardner wrote:[color=blue]
    > I've got a problem that I don't see how to program around. A socket server
    > that was running fine, today started getting an exception from the bind()
    > call (errno 22, Invalid argument) and yet the bind had actually worked.
    >
    > This is apparent from this code: it prints the error message, but then
    > breaks out of the loop and the listen() and accept() calls work normally.
    >
    > How can one handle a function that is both working and raising an
    > exception?
    >
    > sockobj=socket( AF_INET,SOCK_ST REAM)
    > while True:
    > try:
    > sockobj.bind((' ',4321))
    > except socketerror,e:
    > print e
    > if str(e).find('in use') == -1:
    > break
    > print '.'
    > time.sleep(1)
    > sockobj.listen( 5)[/color]

    Is it possible you already have a process bound to that port, and that
    process is handling the incoming connections?

    Otherwise it sounds a little bizarre. In fact even my own attempt at
    explaining doesn't ring true because on Win2k, at least, a second bind
    will raise (10048, 'Address already in use'), and I get a similar error
    on Linux. Rats.

    I take it this code has been copied and pasted? For example, if the host
    were a single space rather than an empty string /that/ might cause this
    problem. Sorry I can't be more help.

    regards
    Steve
    --


    Holden Web LLC +1 800 494 3119

    Comment

    • Michael Fuhr

      #3
      Re: getting socket.bind() exception, but no actual error

      clarence@silcom .com (Clarence Gardner) writes:
      [color=blue]
      > And the whole point of the test in the exception handling suite (checking
      > for "in use") is to repeat the bind until that's not the case. This is, of
      > course, in a program in development which sometimes is not able to be
      > restarted right away after a problem.[/color]

      Why not? Because you get "Address already in use" exceptions due
      to old connections still being in the TIME_WAIT state? If so, are
      you aware that server processes should usually set the SO_REUSEADDR
      socket option before calling bind()? Or is there some other reason
      that bind() fails?

      --
      Michael Fuhr

      Comment

      • Steve Holden

        #4
        Re: getting socket.bind() exception, but no actual error

        Michael Fuhr wrote:
        [color=blue]
        > clarence@silcom .com (Clarence Gardner) writes:
        >
        >[color=green]
        >>And the whole point of the test in the exception handling suite (checking
        >>for "in use") is to repeat the bind until that's not the case. This is, of
        >>course, in a program in development which sometimes is not able to be
        >>restarted right away after a problem.[/color]
        >
        >
        > Why not? Because you get "Address already in use" exceptions due
        > to old connections still being in the TIME_WAIT state? If so, are
        > you aware that server processes should usually set the SO_REUSEADDR
        > socket option before calling bind()? Or is there some other reason
        > that bind() fails?
        >[/color]

        There is some other reason: the exception argument is (errno 22, Invalid
        argument), which is clearly not "Address in use".

        regards
        Steve
        --


        Holden Web LLC +1 800 494 3119

        Comment

        • Michael Fuhr

          #5
          Re: getting socket.bind() exception, but no actual error

          Steve Holden <steve@holdenwe b.com> writes:
          [color=blue]
          > Michael Fuhr wrote:
          >[color=green]
          > > clarence@silcom .com (Clarence Gardner) writes:
          > >[color=darkred]
          > >>And the whole point of the test in the exception handling suite (checking
          > >>for "in use") is to repeat the bind until that's not the case. This is, of
          > >>course, in a program in development which sometimes is not able to be
          > >>restarted right away after a problem.[/color]
          > >
          > > Why not? Because you get "Address already in use" exceptions due
          > > to old connections still being in the TIME_WAIT state? If so, are
          > > you aware that server processes should usually set the SO_REUSEADDR
          > > socket option before calling bind()? Or is there some other reason
          > > that bind() fails?[/color]
          >
          > There is some other reason: the exception argument is (errno 22, Invalid
          > argument), which is clearly not "Address in use".[/color]

          The retry loop likely isn't solving this problem but is rather
          causing it. The code originally posted was:

          sockobj=socket( AF_INET,SOCK_ST REAM)
          while True:
          try:
          sockobj.bind((' ',4321))
          except socketerror,e:
          print e
          if str(e).find('in use') == -1:
          break
          print '.'
          time.sleep(1)
          sockobj.listen( 5)

          Think about what happens if bind() succeeds: the code never breaks
          out of the while loop, so it attempts to call bind() again. On
          most systems that will cause the second call to bind() to fail with
          EINVAL, or "Invalid argument". You could break out of the loop
          when bind() succeeds, but the loop should be unnecessary if you set
          the SO_REUSEADDR socket option before calling bind(), like this:

          sockobj.setsock opt(SOL_SOCKET, SO_REUSEADDR, 1)

          Any decent network programming book (e.g., _UNIX Network Programming_,
          Vol 1, by W. Richard Stevens) will explain that servers should set
          SO_REUSEADDR before calling bind().

          --
          Michael Fuhr

          Comment

          • Clarence Gardner

            #6
            Re: getting socket.bind() exception, but no actual error

            mfuhr@fuhr.org (Michael Fuhr) wrote in message news:<4187d4fc$ 1_4@omega.dimen sional.com>...
            ? Because you get "Address already in use" exceptions due[color=blue]
            > to old connections still being in the TIME_WAIT state? If so, are
            > you aware that server processes should usually set the SO_REUSEADDR
            > socket option before calling bind()? Or is there some other reason
            > that bind() fails?[/color]

            No, that's the only issue. I thought using that option was frowned upon,
            but it's also been a couple of years since I needed to think about such
            things, and I was too lazy to look it up for now.

            Comment

            • Michael Fuhr

              #7
              Re: getting socket.bind() exception, but no actual error

              clarence@silcom .com (Clarence Gardner) writes:
              [color=blue]
              > mfuhr@fuhr.org (Michael Fuhr) wrote in message news:<4187d4fc$ 1_4@omega.dimen sional.com>...
              > ? Because you get "Address already in use" exceptions due[color=green]
              > > to old connections still being in the TIME_WAIT state? If so, are
              > > you aware that server processes should usually set the SO_REUSEADDR
              > > socket option before calling bind()? Or is there some other reason
              > > that bind() fails?[/color]
              >
              > No, that's the only issue. I thought using that option was frowned upon,
              > but it's also been a couple of years since I needed to think about such
              > things, and I was too lazy to look it up for now.[/color]

              SO_REUSEADDR is hardly frowned upon -- quite the contrary: it's
              recommended. See for example the socket bible, _UNIX Network
              Programming_, Vol 1, by W. Richard Stevens. On p 207 (2nd edition),
              in the summary for the Socket Options chapter, Stevens says:

              The most commonly used options that we might encounter are
              SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF, and SO_REUSEADDR. The
              latter should always be set for a TCP server before it calls
              bind.

              Earlier in the chapter, on pp 194-197, Stevens discusses SO_REUSEADDR
              in detail and says that "_All_ TCP servers should specify this
              socket option to allow the server to be restarted in this situation"
              (emphasis his; page numbers may differ in the 3rd edition).

              --
              Michael Fuhr

              Comment

              Working...