做了一個客戶端程式,一般情況下下跑起來沒什么問題。然而,考慮到服務器宕機、斷網的情況,就在客戶端里增加了斷網重連。這個重連就總是出問題。
當socket收發錯誤時,我就簡單地認為網路斷了(或者服務器宕機了),就把socket關閉,然后一直嘗試連接,連上后繼續通信。按網上的資料所說,socket自己不知道是否還連著,得用代碼去判斷,所以我用了個簡單的conn_ok來標記是否連上了。
現在的問題是:在server在線的情況下,client能連上它,把server關掉后,socket就報錯了而且error能被捕捉,捕捉到error后我就做close然后把conn_ok重置一下,socket應該就能重新嘗試連接server了。但是就在重連這里卻報錯:attempt to connect already-connected SSLSocket!。什么?socket還連著嗎?不是已經呼叫close()了嗎?網上又說socket.close()并不是立刻關閉的,想立刻關閉就得先shutdown,加上后,還是一樣。
簡化問題:誰知道怎樣把ssl打包后的socket優雅地斷開,然后重新做連接?
代碼如下:
def send_info_to_server(ip,port,q):
CA_FILE = 'cert'
KEY_FILE = 'pkey'
CERT_FILE = 'cert'
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
context.check_hostname = False
context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE)
context.load_verify_locations(CA_FILE)
# 與服務端建立socket連接
with socket.socket() as sock:
with context.wrap_socket(sock, server_side=False) as ssock:
ssock.settimeout(0.1) #超時0.1,以免阻塞在recv處(有些情況下,客戶端發給服務器資料時,服務器不回傳應答資訊)
conn_ok = False
while True:
while not conn_ok: #如果沒有連接上服務器,每隔5秒嘗試一次
try:
ssock.connect((ip, port))
except socket.gaierror as e:
print ('Address-related error connecting to server: %s' % e)
time.sleep(5)
except socket.error as e:
print ('Connection error: %s' % e)
time.sleep(5)
else:
print('Conntected to: %s' % ip)
conn_ok = True
# 向服務端發送資訊
try:
msg = ('do i connect with server ?')
msg = wrap_info(msg).encode("utf-8")
ssock.send(msg)
except socket.error as e:
print('Send message error: %s' % e)
ssock.shutdown(socket.SHUT_RDWR)
ssock.close()
conn_ok = False
else:
print('Sent message:',msg)
# 接收服務端回傳的資訊
try:
buf = ssock.recv(1024).decode("utf-8")
if not buf:
continue
except socket.error as e:
ssock.shutdown(socket.SHUT_RDWR)
ssock.close()
print('Read message error: %s' % e)
conn_ok = False
else:
print(f"receive msg from server: {buf}")
time.sleep(1)
ssock.close()
if __name__ == '__main__':
send_info = threading.Thread(target=send_info_to_server,args=(cfg['server_ip'],int(cfg['server_port']),info_que))
send_info.start()
send_info.join()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/226510.html
上一篇:YOLO V3 運行提示:RuntimeError: CUDA out of memory. Tried to allocate 18.00 MiB
下一篇:add缺少內置引數
