一、原因淺析
今天在寫一個Python與html5 Websocket 執行個體,麼次終止運行重新運行指令碼總是提示地址已經存在並且被使用!查詢相關文檔才知道在socket編程中,當通過用戶端向伺服器端發送訊息,關閉了串連後,這時如果馬上再去運行伺服器端程式,會提示這個錯誤:
代碼如下:
socket.error: [Errno 98] Address already in use
這是因為在TCP/IP終止串連的四次握手中,當最後的ACK回複發出後,有個2MSL的時間等待,MSL指一個片段在網路中最大的存活時間,這個時間一般是30秒,所以基本上過60秒後就可以重新串連!
為什麼要等待2MSL?是因為在最後發出ACK回複後,發送方不能確認ACK是否被另一端正常收到,如果另一端沒有收到ACK回複的話,將會在1MSL後再次發送FIN片段。所以說發送方等待2MSL時間,也就是剛好它發ACK回複和對方發送FIN片段的時間,如果此時間內都沒有再次收到FIN片段的話,發送方就假設對方已經正常接收到了ACK回複,此時它就會正常關閉串連!
二、解決方案
如果python中socket 綁定的地址正在使用,往往會出現錯誤,
在linux下:
代碼如下:
則會顯示“ socket.error: [Errno 98] Address already in use”
在windows下:
代碼如下:
則會顯示 “socket.error: [Errno 10048] 通常每個通訊端地址(協議/網路地址/連接埠)只允許使用一次”
這是因為socket預設不支援地址複用,如果要複用需要顯示設定,即在綁定前調用setsockop函數t讓通訊端允許地址重用:socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
例如:
代碼如下:
self.recSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.recSocket.settimeout(CHECK_TIMEOUT)
self.recSocket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self.recSocket.bind(('', UDP_PORT))