[問題] C Socket Connect 問題!!

看板C_and_CPP作者 (Center)時間10年前 (2014/01/08 17:02), 編輯推噓6(6040)
留言46則, 6人參與, 最新討論串1/1
各位大大好!! 狀況1: 小弟在寫C Socket 在Server啟動後,Client再啟動 此時第一次連線成功後沒問題!!! 但是我又重新啟動一次Clinet(Server沒重新啟動)這時會連不上線一段一間 之後會 1.連上線(過很長一段時間) 2.完全連不上 狀況2: 當我Server正在連線中時(與Clinet連線中) 我重新啟動Server,再重新啟動Clinet 是可以連的上的 但是我又重新啟動一次Client 之後會 1.連上線(過很長一段時間) 2.完全連不上 請各位幫我想想看是哪邊出了問題? 補一小段程式碼: stcp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); setsockopt(stcp, SOL_SOCKET, SO_REUSEADDR,(void*)&enable, sizeof(enable)); setsockopt(stcp, SOL_SOCKET, SO_REUSEPORT,(void*)&enable, sizeof(enable)); 感謝各位大大!!! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.118.206.95

01/08 17:47, , 1F
server有正常關閉連線嗎? netstat -aln 看看
01/08 17:47, 1F

01/08 17:55, , 2F
因為我是用板子開 所以不是用windows模擬耶
01/08 17:55, 2F

01/08 19:06, , 3F
可以先用wireshark或tcpdump抓封包分析
01/08 19:06, 3F

01/08 19:54, , 4F
看起來是server有問題 可以觀察一下它卡在哪
01/08 19:54, 4F

01/08 19:54, , 5F
不讓client連
01/08 19:54, 5F

01/08 20:21, , 6F
我有用另外一個程式去嘗試連連看Server 是可以連上的
01/08 20:21, 6F

01/08 21:44, , 7F
異常斷線,server必須要timeout才能再接受client連線
01/08 21:44, 7F

01/08 22:10, , 8F
那另一個程式當client,斷線再連 也是上面兩種情況嗎??
01/08 22:10, 8F

01/08 22:14, , 9F
關閉程式不等於正常斷線
01/08 22:14, 9F

01/08 23:21, , 10F
那個程式都正常!! 因為我是用while(1)一直傳接收
01/08 23:21, 10F

01/08 23:22, , 11F
如果我正在連線 然後reset板子 之後就會怪怪
01/08 23:22, 11F

01/08 23:22, , 12F
也不知道如何正常斷線
01/08 23:22, 12F

01/09 02:11, , 13F
處理signal
01/09 02:11, 13F

01/09 10:22, , 14F
應該是你沒有正常關閉連線
01/09 10:22, 14F

01/09 10:22, , 15F
你沒呼叫close(fd)
01/09 10:22, 15F

01/09 15:41, , 16F
因為我是直接reset板子 所以應該是Client不正常
01/09 15:41, 16F

01/09 15:42, , 17F
關閉 導致要等到timeout? 或是永遠都連不上了?
01/09 15:42, 17F

01/09 19:11, , 18F
貼的程式碼就像腳癢卻給我看額頭. 沒連線斷線的相關處理啊...
01/09 19:11, 18F

01/09 21:45, , 19F
板子的client 是自己寫的嗎?? 是不是重用socket連線時
01/09 21:45, 19F

01/09 21:47, , 20F
又用跟第一次連線 同樣的port去bind socket
01/09 21:47, 20F

01/10 00:31, , 21F
重開板子 就會用一樣port去連他
01/10 00:31, 21F

01/10 11:20, , 22F
那可以改不同port試看看
01/10 11:20, 22F

01/10 17:02, , 23F
如果願意提供完整socket部份的程式碼會更方便debug
01/10 17:02, 23F

01/10 21:53, , 24F
Server 端 CODE 網址 http://codepad.org/CxpgQkSH
01/10 21:53, 24F

01/10 21:54, , 25F
Client 端 CODE 網址 http://codepad.org/yoinQcP0
01/10 21:54, 25F

01/10 21:54, , 26F
再麻煩大家了~
01/10 21:54, 26F

01/11 02:00, , 27F
Server的Line53-66,接受新連線後,若舊連線還存在,就關掉新的.
01/11 02:00, 27F

01/11 02:01, , 28F
問題是你直接reset版子,而不是送出斷線訊息給Server,因此
01/11 02:01, 28F

01/11 02:03, , 29F
Server認為舊連線仍存在,需一段時間後,Server端才會認為斷線.
01/11 02:03, 29F

01/11 02:04, , 30F
其中一種解決方式可以 google: tcp keepalive
01/11 02:04, 30F

01/11 02:07, , 31F
tcp keepalive howto
01/11 02:07, 31F

01/11 02:11, , 32F
或者,接受新連線後,若舊連線還存在,看情況決定關掉新的或舊的.
01/11 02:11, 32F

01/11 02:20, , 33F
另一個問題是,Server以為舊連線還存在,Line99-151的部分,
01/11 02:20, 33F

01/11 02:21, , 34F
也可能因此卡在recv()中,直到Server系統認為斷線才跳出.
01/11 02:21, 34F

01/11 02:24, , 35F
上述的 tcp keepalive 方式, 也算是可以一併解決此問題.
01/11 02:24, 35F

01/11 11:34, , 36F
感謝yvb大大 請問要怎麼由Server關掉舊的連線
01/11 11:34, 36F

01/11 11:41, , 37F
tcp keepalive設定好像在c沒有耶
01/11 11:41, 37F

01/11 11:43, , 38F
setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,&optval,optlen)
01/11 11:43, 38F

01/11 11:44, , 39F
請問最後兩個參數是什麼?
01/11 11:44, 39F

01/11 12:32, , 40F
我上面所指的舊連線就是你的stcpactive,是相對stcpbusy而言,
01/11 12:32, 40F

01/11 13:16, , 41F
至於怎麼關掉stcpactive,Line201-204不就是做這樣的事?
01/11 13:16, 41F

01/11 13:18, , 42F
當然Line53的accept()最好驗證一下回傳值.
01/11 13:18, 42F

01/11 13:19, , 43F
至於socketopt(..., SO_KEEPALIVE, ...)的參數,
01/11 13:19, 43F

01/11 13:22, , 44F
意同本文所提socket(..., SO_REUSEADDR, ...)的enable兩參數.
01/11 13:22, 44F

01/11 13:23, , 45F
^你本文所提
01/11 13:23, 45F

01/11 13:35, , 46F
非常感謝 我再試試看 accept的確要加回傳直 3Q
01/11 13:35, 46F
文章代碼(AID): #1IpHGN7H (C_and_CPP)