c++ linux accept() blocking after socket closed

后端 未结 5 1409
醉话见心
醉话见心 2020-12-09 13:32

I have a thread that listens for new connections

new_fd = accept(Listen_fd, (struct sockaddr *) & their_addr, &sin_size);

and anoth

5条回答
  •  北荒
    北荒 (楼主)
    2020-12-09 13:49

    Use: sock.shutdown (socket.SHUT_RD)

    Then accept will return EINVAL. No ugly cross thread signals required!

    From the Python documentation: "Note close() releases the resource associated with a connection but does not necessarily close the connection immediately. If you want to close the connection in a timely fashion, call shutdown() before close()."

    http://docs.python.org/3/library/socket.html#socket.socket.close

    I ran into this problem years ago, while programming in C. But I only found the solution today, after running into the same problem in Python, AND pondering using signals (yuck!), AND THEN remembering the note about shutdown!

    As for the comments that say you should not close/use sockets across threads... in CPython the global interpreter lock should protect you (assuming you are using file objects rather than raw, integer file descriptors).

    Here is example code:

    import socket, threading, time
    
    sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind (('', 8000))
    sock.listen (5)
    
    def child ():
      print ('child  accept ...')
      try:  sock.accept ()
      except OSError as exc :  print ('child  exception  %s' % exc)
      print ('child  exit')
    
    threading.Thread ( target = child ).start ()
    
    time.sleep (1)
    print ('main   shutdown')
    sock.shutdown (socket.SHUT_RD)
    
    time.sleep (1)
    print ('main   close')
    sock.close ()
    
    time.sleep (1)
    print ('main   exit')
    

提交回复
热议问题