作者Liang8057 (Center)
看板C_and_CPP
標題[問題] C Socket Connect 問題!!
時間Wed Jan 8 17:02:11 2014
各位大大好!!
狀況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
→ pcjustin:server有正常關閉連線嗎? netstat -aln 看看 01/08 17:47
→ Liang8057:因為我是用板子開 所以不是用windows模擬耶 01/08 17:55
→ pcjustin:可以先用wireshark或tcpdump抓封包分析 01/08 19:06
→ laing20333:看起來是server有問題 可以觀察一下它卡在哪 01/08 19:54
→ laing20333:不讓client連 01/08 19:54
→ Liang8057:我有用另外一個程式去嘗試連連看Server 是可以連上的 01/08 20:21
推 johnpage:異常斷線,server必須要timeout才能再接受client連線 01/08 21:44
→ laing20333:那另一個程式當client,斷線再連 也是上面兩種情況嗎?? 01/08 22:10
推 johnpage:關閉程式不等於正常斷線 01/08 22:14
→ Liang8057:那個程式都正常!! 因為我是用while(1)一直傳接收 01/08 23:21
→ Liang8057:如果我正在連線 然後reset板子 之後就會怪怪 01/08 23:22
→ Liang8057:也不知道如何正常斷線 01/08 23:22
→ pcjustin:處理signal 01/09 02:11
推 jimmytzeng:應該是你沒有正常關閉連線 01/09 10:22
→ jimmytzeng:你沒呼叫close(fd) 01/09 10:22
→ Liang8057:因為我是直接reset板子 所以應該是Client不正常 01/09 15:41
→ Liang8057:關閉 導致要等到timeout? 或是永遠都連不上了? 01/09 15:42
推 yvb:貼的程式碼就像腳癢卻給我看額頭. 沒連線斷線的相關處理啊... 01/09 19:11
→ laing20333:板子的client 是自己寫的嗎?? 是不是重用socket連線時 01/09 21:45
→ laing20333:又用跟第一次連線 同樣的port去bind socket 01/09 21:47
→ Liang8057:重開板子 就會用一樣port去連他 01/10 00:31
→ laing20333:那可以改不同port試看看 01/10 11:20
→ pcjustin:如果願意提供完整socket部份的程式碼會更方便debug 01/10 17:02
→ Liang8057:再麻煩大家了~ 01/10 21:54
推 yvb:Server的Line53-66,接受新連線後,若舊連線還存在,就關掉新的. 01/11 02:00
→ yvb:問題是你直接reset版子,而不是送出斷線訊息給Server,因此 01/11 02:01
→ yvb:Server認為舊連線仍存在,需一段時間後,Server端才會認為斷線. 01/11 02:03
→ yvb:其中一種解決方式可以 google: tcp keepalive 01/11 02:04
→ yvb: tcp keepalive howto 01/11 02:07
→ yvb:或者,接受新連線後,若舊連線還存在,看情況決定關掉新的或舊的. 01/11 02:11
→ yvb:另一個問題是,Server以為舊連線還存在,Line99-151的部分, 01/11 02:20
→ yvb:也可能因此卡在recv()中,直到Server系統認為斷線才跳出. 01/11 02:21
→ yvb:上述的 tcp keepalive 方式, 也算是可以一併解決此問題. 01/11 02:24
→ Liang8057:感謝yvb大大 請問要怎麼由Server關掉舊的連線 01/11 11:34
→ Liang8057:tcp keepalive設定好像在c沒有耶 01/11 11:41
→ Liang8057:setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,&optval,optlen) 01/11 11:43
→ Liang8057:請問最後兩個參數是什麼? 01/11 11:44
推 yvb:我上面所指的舊連線就是你的stcpactive,是相對stcpbusy而言, 01/11 12:32
→ yvb:至於怎麼關掉stcpactive,Line201-204不就是做這樣的事? 01/11 13:16
→ yvb:當然Line53的accept()最好驗證一下回傳值. 01/11 13:18
→ yvb:至於socketopt(..., SO_KEEPALIVE, ...)的參數, 01/11 13:19
→ yvb:意同本文所提socket(..., SO_REUSEADDR, ...)的enable兩參數. 01/11 13:22
→ yvb: ^你本文所提 01/11 13:23
→ Liang8057:非常感謝 我再試試看 accept的確要加回傳直 3Q 01/11 13:35