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

TIdTCPServer送資料給所有Client時是否可用多工

答題得分者是:Vicen
Clarinet
高階會員


發表:9
回覆:97
積分:126
註冊:2002-05-08

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-11-03 12:24:52 IP:61.30.xxx.xxx 未訂閱
請問各位大大: 我有一個程式,開了二個Server,一個Server負責接收資料,另一個負責把接收的資料解析處理完後再送資料給連入的Client,送給Client的方式如下。 現有一個問題,即此段Code能使用多工的方式傳送嗎?需要注意那些方面? 因為,收==>處理資料==>送出資料,這樣的流程之下,若送出資料的部份有塞住的話,則會影響"收"的部份,目前發現到,"收"的資料有時會不完整。 而把"送出資料"關閉之後,就一切正常! 所以,才想到是否能以多工來解決,且需要注意那些方面!    
  List :=idSendServer.Threads.LockList;
  try
   if List.Count <=0 then Exit;       for i :=0 to List.Count -1 do
   begin
    try
     try
      with TIdPeerThread(List.Items[i]) do
      begin
       if (Terminated) or (Connection.Connected =False) then Continue;
       
       AIP :=Connection.Socket.Binding.PeerIP;
       Connection.WriteLn(ASendData);
      end;//end with TIdPeerThread
     except
      on E :Exception do
      begin
       LogFile(Format('%s%s\ErrSend.txt', [LogPath, FormatDateTime('YYYYMMDD', Date)]), Format('PassDataToClientWriteln:(i:%d)%s, %s, %s', [i, AIP, E.Message, ASendData]));
       TIdPeerThread(List.Items[i]).Stop;
      end;
     end;
    except
     on E :Exception do
      LogFile(Format('%s%s\ErrSend.txt', [LogPath, FormatDateTime('YYYYMMDD', Date)]), Format('PassDataToClientException:(i:%d)%s, %s', [i, AIP, E.Message]));
    end;
   end;
  finally
   idSendServer.Threads.UnlockList;
  end;
謝謝各位大大! GPS(全球衛星定位系統) http://www.allgps.com
------
GPS(全球衛星定位系統)
http://www.allgps.com
Vicen
高階會員


發表:13
回覆:145
積分:151
註冊:2005-03-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-11-10 16:23:58 IP:221.226.xxx.xxx 未訂閱
TIdTCPServer本身就是一个多线程的组件,个人觉得没有必要用2个SERVER,如果你担心处理的数量大,可以在SERVER接受资料后开个线程处理资料,处理好了再由线程传回结果。    大概流程是:    (SERVER) [接收资料] -> [保存客户端记录号] -> [创建处理线程] -> [传回处理结果]    这个过程中并不影响SERVER的正常工作。而多开一个SERVER不但增加了你自己的程序量,而且也无形中加大了系统的额外开销,一般情况下,一个SERVER带个100-200的客户端还是比较轻松的,当然当客户端数量多了后,线程的使用是必不可少的,否则大家就都要排队等了,祝你好运~     發表人 -
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-11-11 08:38:55 IP:203.69.xxx.xxx 未訂閱
      begin
       if (Terminated) or (Connection.Connected =False) then Continue;
       
       AIP :=Connection.Socket.Binding.PeerIP;
       Connection.WriteLn(ASendData);
      end;//end with TIdPeerThread
問一下喔, 您的這段程式碼顯示每一個連上的 Client 都要收到相同的訊息, 對嗎?
Clarinet
高階會員


發表:9
回覆:97
積分:126
註冊:2002-05-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-11-14 10:47:21 IP:61.30.xxx.xxx 未訂閱
引言:
      begin
       if (Terminated) or (Connection.Connected =False) then Continue;
       
       AIP :=Connection.Socket.Binding.PeerIP;
       Connection.WriteLn(ASendData);
      end;//end with TIdPeerThread
問一下喔, 您的這段程式碼顯示每一個連上的 Client 都要收到相同的訊息, 對嗎?
對!這一段程式碼會送出相同的訊息給所有連上的Client GPS(全球衛星定位系統) http://www.allgps.com
------
GPS(全球衛星定位系統)
http://www.allgps.com
Clarinet
高階會員


發表:9
回覆:97
積分:126
註冊:2002-05-08

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-11-14 11:13:31 IP:61.30.xxx.xxx 未訂閱
引言: TIdTCPServer本身就是一个多线程的组件,个人觉得没有必要用2个SERVER,如果你担心处理的数量大,可以在SERVER接受资料后开个线程处理资料,处理好了再由线程传回结果。 大概流程是: (SERVER) [接收资料] -> [保存客户端记录号] -> [创建处理线程] -> [传回处理结果] 这个过程中并不影响SERVER的正常工作。而多开一个SERVER不但增加了你自己的程序量,而且也无形中加大了系统的额外开销,一般情况下,一个SERVER带个100-200的客户端还是比较轻松的,当然当客户端数量多了后,线程的使用是必不可少的,否则大家就都要排队等了,祝你好运~ 發表人 - >< face="Verdana, Arial, Helvetica"> vicen你好! 我再描述一下,我有一個Server A,負責接收資料;另一個Server B,負責送出資料至所有連入的Client。 因為,都是即時的收送資料,因為,每秒資料量很大,所以,不能有任一端影響速度! 目前,收資料不會有影響,而問題是出在送資料至Client端。測試結果,若有任一個Client端延遲接收資料的話,就會影響我程式後面的動作。 在我下Connection.Writeln(ASendData)時,若有一個Client自己本身反應較慢的話,就會使我的程式也跟著受影響。 所以,才想說送資料至所有Client端的程式是否可改成多工的做法,也就是此段程式碼,若可開Thread 來處理送資料的動作時,應該要注意那些事情。 目前統計完後,每秒最大處理量約有七、八十筆資料要送出。若每一筆都開一個Thread來傳送,是否有那些影響呢? GPS(全球衛星定位系統) http://www.allgps.com
------
GPS(全球衛星定位系統)
http://www.allgps.com
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-11-14 12:32:10 IP:203.69.xxx.xxx 未訂閱
每秒 6,70 筆要傳喔... 用 Queue Threads 吧..... Queue中記錄要傳的Data及Client資料, 用ㄧ個 Thread (假設是 ResponseManageTrd), ResponseManageTrd 會持續檢查 Queue 內是否有資料要傳, 若有資料要傳, 就針對每一筆資料啟動一個 Thread 傳送資料, 在這部份可以額外作ㄧ個 thread 數目限制. 假設是 MaxRMTrdCnt thread 數目上限, 如果 目前正在傳送的Thread數目〈MaxRMTrdCnt, ResponseManageTrd 就會開新Thread 傳送資料,不然就 Sleep(100), 等thread 數目下降... 如果要做 重送的動作或LOG 可以在每個 傳送資料的 Thread 中的 OnTerminate Event 做動作.... 重送.... 將資料填回Queue(重送次數加1) LOG..... 失敗或重送n次失敗, 錯誤訊息寫入LOG 我的想法是這樣, 希望您看的懂... 發表人 - malanlk 於 2005/11/14 12:34:27
shaomaif
一般會員


發表:10
回覆:8
積分:3
註冊:2005-11-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-11-14 14:29:05 IP:61.171.xxx.xxx 未訂閱
如果你覺得一個縣程發送太慢 建議多開几個縣程同時發送
Vicen
高階會員


發表:13
回覆:145
積分:151
註冊:2005-03-14

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-11-14 20:43:28 IP:221.226.xxx.xxx 未訂閱
Indy Tcp Server本身为多线程的,所以服务端接收不会受到影响,但注意的是接收资料存储变量一定不为全局,否则就会出问题了。    至于处理资料方面,不论你每秒处理量是多少,我们要做的就是协调程序流程,毕竟网络延时、错误都随时可能发生,所以处理和发送端可暂不考虑流量问题,这样你反而会深陷其中,只要处理程序得当,线程之间不会相互干扰,做到这些后再适当优化算法即可。    你在下Writeln(ASendData)时,如果是在新的线程中,哪怕会暂时挂住,也不会影响服务器主线程的工作。    给您提供一下我常规应付这类大流量的方法,在我这里称之为多线程流水线作业。为了避免影响网络和服务器运作,根据实际情况将资料并发处理线程限定为10-20条(当然你可以适当增加),创建一个链表,用来记录接收到的资料以及客户端句柄。    记录链表 X ---------- 客户端句柄 + 接收的资料 客户端句柄 + 接收的资料 客户端句柄 + 接收的资料    服务器端只负责将接收的资料和客户端句柄记录到链表,不去处理。    服务器(接收资料时) ------------------- 记录当前收到的资料和客户端句柄到链表 X 中。    调度中心 -------- 调度中心通常来说就是任务调度,你可以使用一个每10毫秒(时间可以协调)运行一次的TIMER或者创建一条单独的线程,通过它将链表中的任务分配给线程处理,通常流程如下:    
    调度流程
    --------
    (0) 检查是否有资料在链表中等待处理
    (1) 检查是否有空闲线程
        (这里是为了防止创建过多的线程而影响网络或服务器的运行)
        (你可以用一个全局变量来约束并发线程数量,例如 INTEGER变量来做运行中计数)
        (或创建一个ARRAY[1..MAX THREAD]的BOOLEAN数组来标志线程运作情况)
    (2) 创建线程处理链表当前顶部记录
    (3) 删除链表记录
    
    (0)-(3) 是一个循环,只要有记录进入链表,就会立刻被调度分配工作。
大概流程也就是这样,但具体如何应用就要根据你的具体情况来定了,但模式就是这样,如果你不太了解线程可以学习一下,DELPHI使用线程还是比较方便的。
Clarinet
高階會員


發表:9
回覆:97
積分:126
註冊:2002-05-08

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-11-16 10:43:55 IP:61.30.xxx.xxx 未訂閱
引言: 恕刪.........
感謝各位大大提供的解決方法! 這幾天找了一些資料,才發覺到原來Indy是一個blocking的機制,所以需要等後對方回應後才會繼續下去,因此Writeln()的動作,會受Client端影響。 因此,我在大量送出資料時,會被某個Client所咬住,而影響系統的運作。 目前最快的解決方式,我多寫了一個中間轉發的程式,此程式使用Delphi 5 的TCPServer和TCPClient來做中繼站轉發資料!因為,TCPServer可使用Non-blocking的方式,所以,就不用受限於各Client的運作。 感謝各位大大提供的方式,更感謝Vince提供如此詳細的做法! 謝謝你們了!有時間的話,會完成各位大大提供的方式。 目前先以轉發程式來解決燃眉之際! 謝謝各位! GPS(全球衛星定位系統) http://www.allgps.com
------
GPS(全球衛星定位系統)
http://www.allgps.com
系統時間:2024-05-15 2:58:57
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!