ServerSocket1->Socket->Connections[i]問題 |
答題得分者是:aftcast
|
addn
高階會員 發表:64 回覆:221 積分:202 註冊:2005-03-21 發送簡訊給我 |
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
你好,這幾天比較忙,本來有計劃要回你的(記得上回你最後也問了這個問題)…
這分成二種: 第一種: 比較容易的方式,當對方的ip是固定的時候,你可以用 ServerSocket1->Socket->Connections[i]->RemoteAddress 比對client的固定ip,若相等,那就是你所知道的那個client。 第二種: 來源的ip你根本不知道…這就難了點,因為你必需制定protocol,即在client connect 後在接放封包的時候去比對封包的內容。以例子來說就像online game一樣,在玩之前一定要login,而client端一定會輸入帳號與密碼,這些資料傳給server後,server去比對資料,若是你所"認識"的,你就把 這個 i 指定給一個全域型的變數。當你想把資料傳給這位認識的client時,就找到這個全域變數(已設成i的值),然後ServerSocket1->Socket->Connections[全域變數]->SendBuf(...... ) 有件事要特別注意,client可能會建立不只一次的連線,原因很多,暫不管。而這時候你就要在 connect 的事件上,先比對該client是否已連線,若是,就把舊的close,把此時的(新的) i 值設定給全域變數。簡單講就是保持一個client一個連線。(除非你希望一個client可以有數個連線) 上回你有提到 block 與 非block的差別,其實主要的差別是 block的socket是指該socket 在讀 或寫資料時,會痴痴的一直等待對方的回應或寫完時才離開該讀或寫的函式。這樣的結果會造成程式好像停住了,畫面都不動。也因為這樣的關系 block 通常要配合thread,在thread中使用block 的函式時user不會感覺到畫面停住。 而非block型的就相反,它會在對方送完整資料後再通知去讀,而寫的時候則是馬上寫出去,不等對方是否接到… 這種型態的socket 就不會有畫面停住的情形。一般用這種型的較多。 ===================引 用 addn 文 章=================== 各位大大 請問要怎判斷ServerSocket1->Socket->Connections[i] 對應的是那一個連線的client呢? 謝謝
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
addn
高階會員 發表:64 回覆:221 積分:202 註冊:2005-03-21 發送簡訊給我 |
您好
感謝大大回覆 1. 第一種我懂了,可是第二種有點不了解 而我只有用一台電做腦測試RemoteAddress都是 一樣127.0.0.1,那要怎做才能分辨哪一個client呢? 可以用SocketHandle來做嗎?每次有新client連線時 server將SocketHandle 送給新client,然後client就用這個Handle碼 再去跟server溝通,這樣server就可藉Handle去找到正確的Connection[i]了 2. server可以用廣播方式同時將資料送給所有已連線的client嗎? (不用for loop方式一個一個送) 3. 如果client與server連線後,有很長一段時間閒置,會被server強制disconnect嗎? 如果會的話一般會用什麼機制來防止client被踢掉 謝謝 |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
1/ 你說的handle方式應該是可行,這也算是你制定的protocol,即以handle來做彼此的辦識。我想handle正常情形下應該不會重複。
2/ 就我所知TCP/IP 的協定應該無法用在廣播?! 即使你使用了廣播的ip。我沒試過,因為我若是需要用廣播的方式,一般是用UDP的協定。當然若你所謂的廣播不是指所有網段上的(區網)的廣播,而只是對於某些特定數量的來發送同一訊息,那麼就肯定要用for 了! 3/ 我還沒遇到因idle而被踢的情形,但一般來講,我會在ServerSocket1ClientError事件上加上 [code cpp] ErrorCode = 0; Socket->Close(); [/code] 而在client端程式的ClientSocketError事件上加入 [code cpp] ErrorCode = 0; try { dynamic_cast dynamic_cast } catch (...) { } [/code]
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
addn
高階會員 發表:64 回覆:221 積分:202 註冊:2005-03-21 發送簡訊給我 |
您好
測試結果handle可以解決上一個問題 現在又遇到新問題了,我在寫簡易的聊天室程式 程式中Server用for連續送資料給每個client 如下 for ( i=0; i < Num ; i ) { ServerSocket1->Socket->Connections[i]->SendText(Buf); } 這樣正常 可是用Server 用for連續送資料到同一個client就會發生資料lose問題 如下 for( i = 0;i < Num ; i ) { ServerSocket1->Socket->Connections[ j ]->SendText(Buf); } 如果有加一段足夠的delay時間資料就不會再發生loss了 for(int l=0;l<10000000;l ) {}...................................................加上的delay程式 我推測可能是Server端資料還沒發送完成,又有新資料進來,把舊的覆蓋掉 請問是這樣嗎?還是client端來不及接收資料呢? ServerSocket有沒有方法可以知道,目前傳送的資料是否完成了呢? (因為我不想用delay方式) 謝謝 |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
我認為是client端來不及「一次一次」的收。為何說是一次一次? 比如說server 陸續的送出如下資料
ABC DEF GHI 在client端你可能認為你會收到 ABC DEF GHI ,但事實上有可能會收到 ABCDE FGH I 這類的,於是你的程式判別就會出錯。要解決這問題的話,你可以用最簡單的方式,比如說在結尾插入一個不會使用的字(值),比如說X(當然x不好,說明而已) ABCX DEFX GHIX 而收到時就算是 ABCXDE FXGH IX 你也可以用組合與找x的方式出取你要的資料。
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2009-04-15 00:15:13, 註解 無‧
|
brange
一般會員 發表:6 回覆:9 積分:3 註冊:2007-07-04 發送簡訊給我 |
|
addn
高階會員 發表:64 回覆:221 積分:202 註冊:2005-03-21 發送簡訊給我 |
|
kostin
一般會員 發表:18 回覆:43 積分:22 註冊:2010-03-11 發送簡訊給我 |
請問 用SocketHandle 來辨識 Client
是如何的用法阿?? 我目前適用for迴圈 有幾個client 就傳幾次 Client 再解碼 看資料是不是給自己的 再來小弟想到的是紀錄 連線順序 與 Client 的IP 去對應 可是在Client登入登出 紀錄會很麻煩 請教一下 所以 請問 用SocketHandle 來辨識 Client 是如何的用法阿?? 感恩
------
工程師的世界太深奧了 ~ 總是有不斷的驚奇發生 在解決問題的當下 , 才能確認我的存在 在得到幫助的當下 , 才能發現我不孤單 |
addn
高階會員 發表:64 回覆:221 積分:202 註冊:2005-03-21 發送簡訊給我 |
您好
你的方法可行,不過比較麻煩, client端會有近出情形,Server端的連線順序會一直改變, 所以用IP 連線順序判別並不好作,而且也有可能同一IP 可能開好幾個Client連線狀況, 建議用handle IP或handle來作Client端的識別方式 ex: 要送資料給其中的一個client 先用迴圈找出client目前是放在第幾個Connections[i]連線陣列內 loop: int k; k=ServerSocket->Socket->Connections[i]->SocketHandle; 當k=要找的hamdle時,i 就是這個client所在的連線陣列內的位址順序, 然後ServerSocket1->Socket->Connections[i]->SendText(XXXX); ===================引 用 kostin 文 章=================== 請問 用SocketHandle 來辨識? Client 是如何的用法阿?? 我目前適用for迴圈 有幾個client 就傳幾次 Client 再解碼? 看資料是不是給自己的 再來小弟想到的是紀錄 連線順序 與 Client 的IP? 去對應 可是在Client登入登出 紀錄會很麻煩 請教一下? 所以 請問 用SocketHandle 來辨識? Client 是如何的用法阿?? 感恩 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |