作者streitleak (亞斯爾‧馮‧修特萊)
看板C_and_CPP
標題Re: [問題] socket在第一次recv後 會自動斷線
時間Wed Jun 29 18:09:43 2011
※ 引述《werbnm (懶懶懶)》之銘言:
: do{
: /*n = strlen(send_buf);
: send_buf[n] = '\0';*/
: if( send(s, send_buf, MAXLINE, 0) == SOCKET_ERROR)
: cerr << "Send message error\n" << send_buf;
: else
: cout << "Client send:\n" << send_buf;
: if( (n = recv(s, recv_buf, MAXLINE, 0)) == 0){
: cerr << "Connection closed\n";
: break;
: }
: else if( n == SOCKET_ERROR){
: cerr << "Received error\n" << WSAGetLastError();
: break;
: }
: else{
: recv_buf[n] = '\0';
: cout << recv_buf;
: }
: 跑完第一次 就中斷了
: }while( fgets(send_buf, MAXLINE, stdin) != NULL );
用推文回不太方便。
D網友跟我要講得東西是一樣的,do while迴圈的特性是,他一定會執行一次。
也就是說不管你有沒有從stdin輸入任何東西,他都一定會跑send recv一次。
然後因為fget如果在檔案結尾或沒有收到任何字元時,他會回傳一個null pointer。
所以自然就跳出迴圈了,後面你要再送的時候,自然因為server端偵測到client這邊
斷了,它也自動把socket關閉了。當你client要連到同一個socket的時候,
server因為已經把舊的socket關掉了,所以連不上,自然會收到reset by peer的
錯誤訊息。
通常socket的寫法如d網友說得,都是用while(條件)做處理。
Ex:
bool terminated = false;
int timeup=0;
while(!terminated)
{
if( fgets(send_buf, MAXLINE, stdin) == NULL )
{
timeup++;
if( timeup > 60000 ) terminated=true; //10分鐘沒輸入過資料的話
sleep(10);
continue;
}
else
{
if( strcpy(send_buf,"disconnect") == 0 )
{
terminated == true;
}
else
{
你的程式碼
}
}
}
這樣就不會因為while條件的關係找不到問題點,而且將來要修改也會比較方便。
PS:本來不想發的,結果按錯鍵,昏倒。
PS2:有錯歡迎指正,好久沒寫了。
--
星たちよ
汝の命短き眷族の望みな聞くがよい
我らの望み それほ
汝の本將ちゆく末な看取るニと
-------------《アーヴによる人類帝國》國歌の一節よリ
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.218.4.98
※ 編輯: streitleak 來自: 61.218.4.98 (06/29 18:09)
※ 編輯: streitleak 來自: 61.218.4.98 (06/29 18:10)
※ 編輯: streitleak 來自: 61.218.4.98 (06/29 18:15)
※ 編輯: streitleak 來自: 61.218.4.98 (06/29 18:20)
※ 編輯: streitleak 來自: 61.218.4.98 (06/29 18:28)
推 tropical72:強!!小挑一下:"fgets..沒有收到任何字元時", 應是只有 06/29 18:24
→ tropical72:在 EOF 時會傳回NULL,若為stdin,則是ctrl+d/z 送出EOF 06/29 18:24
※ 編輯: streitleak 來自: 61.218.4.98 (06/29 18:32)
推 werbnm:首先先謝謝你熱心回應,但我只貼出部份程式碼 所以造成誤解 06/29 18:38
→ werbnm:會用do-while是因為一開始的確有輸入 06/29 18:39