全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3551
推到 Plurk!
推到 Facebook!

ServerSocket1->Socket->Connections[i]問題

答題得分者是:aftcast
addn
高階會員


發表:64
回覆:221
積分:202
註冊:2005-03-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-04-09 20:21:39 IP:114.47.xxx.xxx 訂閱
各位大大

請問要怎判斷ServerSocket1->Socket->Connections[i]
對應的是那一個連線的client呢?

謝謝
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-04-09 21:57:40 IP:122.120.xxx.xxx 訂閱
你好,這幾天比較忙,本來有計劃要回你的(記得上回你最後也問了這個問題)…

這分成二種:

第一種: 比較容易的方式,當對方的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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-04-10 09:19:24 IP:114.47.xxx.xxx 訂閱
  您好
感謝大大回覆
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
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-04-10 10:36:15 IP:210.64.xxx.xxx 訂閱
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(Sender)->Close();
dynamic_cast(Sender)->Open();
}
catch (...)
{
}

[/code]

------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2009-04-10 10:39:02, 註解 無‧
aftcast 重新編輯於 2009-04-10 10:42:48, 註解 無‧
addn
高階會員


發表:64
回覆:221
積分:202
註冊:2005-03-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-04-13 21:40:00 IP:114.40.xxx.xxx 訂閱
 您好
測試結果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方式)
謝謝
編輯記錄
addn 重新編輯於 2009-04-13 21:44:06, 註解 無‧
addn 重新編輯於 2009-04-13 21:45:19, 註解 無‧
addn 重新編輯於 2009-04-13 21:45:57, 註解 無‧
addn 重新編輯於 2009-04-13 21:48:43, 註解 無‧
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-04-15 00:14:27 IP:59.115.xxx.xxx 訂閱
我認為是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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2009-06-06 02:42:53 IP:140.131.xxx.xxx 訂閱
請問SocketHandle怎麼使用的呢?
因為我也該好遇到同樣的問題了,手邊的相關書籍都沒有介紹到有關SocketHandle細節的內容,謝謝。
addn
高階會員


發表:64
回覆:221
積分:202
註冊:2005-03-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2009-06-06 09:09:36 IP:114.47.xxx.xxx 訂閱
您好
可以用
int k;
k=ServerSocket->Socket->Connections[i]->SocketHandle;

判斷k
這樣就可找出Connections[i]對應的是那一個SocketHandle
kostin
一般會員


發表:18
回覆:43
積分:22
註冊:2010-03-11

發送簡訊給我
#9 引用回覆 回覆 發表時間:2010-04-05 05:00:07 IP:218.162.xxx.xxx 訂閱
請問 用SocketHandle 來辨識 Client
是如何的用法阿??

我目前適用for迴圈 有幾個client 就傳幾次
Client 再解碼 看資料是不是給自己的

再來小弟想到的是紀錄
連線順序 與 Client 的IP 去對應
可是在Client登入登出 紀錄會很麻煩

請教一下 所以
請問 用SocketHandle 來辨識 Client
是如何的用法阿??

感恩
------
工程師的世界太深奧了 ~ 總是有不斷的驚奇發生
在解決問題的當下 , 才能確認我的存在
在得到幫助的當下 , 才能發現我不孤單
addn
高階會員


發表:64
回覆:221
積分:202
註冊:2005-03-21

發送簡訊給我
#10 引用回覆 回覆 發表時間:2010-04-06 08:28:20 IP:114.47.xxx.xxx 訂閱
您好
你的方法可行,不過比較麻煩,
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
是如何的用法阿??

感恩

系統時間:2017-12-12 8:35:45
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!