2017-01-04 8 views
3

デルファイのScktComp.dcuでTServerSocketを使用して、単一のファイルストリームまたはマルチファイルストリームをMulti TClientSocket ...に送信するソリューションがありますか? 私はここにこのコードを持っている:私は正確に何が必要TServerSocketからMulti TClientSocketへのストリーム送信の同期化方法

procedure TFrmMainServer.ServerSocket1ClientConnect(Sender: TObject; 
    Socket: TCustomWinSocket); 
var 
    a, ACount: integer; 
    MyText: String; 
    MyBuffer: pchar; 
    MyStream: TMemoryStream; //or TFileStream; 
begin 
... 
... 
... 
    for a := 0 to ServerSocket1.Socket.ActiveConnections - 1 do 
    begin 
     ServerSocket1.Socket.Connections[a].SendText(MyText); 
     // or 
     //ServerSocket1.Socket.Connections[a].SendStream(Mystream); // for files transfering .... 
     // or 
     //ServerSocket1.Socket.Connections[a].SendBuf(MyBuffer, ACount); 
    end; 
end; 

は私がマルチはTClientSocketに任意のファイルストリームまたは任意のテキストまたは任意のコマンドを転送したり、送信できるように良い表現ではなくてループ機能を交換することです私のサーバーに接続されているすべてのクライアントが、自分のTClientServerが同時に送信または転送しているものを受信し、他のクライアントを失うことなく、または1人ずつ他の人に送信することなく受信する必要があることを意味します... 最後に、このコンポーネントでは、返信してくれた方々のご意見をお待ちしております。

答えて

3

複数のクライアントに同じデータを送信する場合は、ループを回避することはできません。 TCPには、複数のクライアントにデータをブロードキャストする概念がないため、コードで手動で実装する必要があります。これは通常、クライアントごとにデータのコピーを作成して、データを並行して送信できるようにすることを意味します。

これを処理するには2つの方法があり、どちらもクライアントごとの送信データバッファを使用する必要があります。 TServerSocket.OnClientConnectイベントを使用してバッファーのTMemoryStreamを作成し、それをTCustomWinSocket.Dataプロパティに割り当てて、簡単に追跡できるようにします。あなたのコードに合ったものを使用してください。

  1. 各クライアントが専用のワーカースレッドで実行されるように、サーバーをスレッドブロッキングモードにします。クリティカルセクションでデータバッファをラップします。特定のクライアントにデータを書きたいときは、クライアントのバッファをロックし、バッファの最後にデータを追加してロックを解除します。クライアントのワーカースレッドが新しいデータのバッファを継続的にチェックし、クライアントのソケットを介して送信するようにします。転送したバイトをバッファの先頭から削除します。

  2. サーバーを非ブロックモードにして、ワーカースレッドまたはロックを使用しないようにします。特定のクライアントにデータを書きたいときは、クライアントのバッファにすでに送信されていないバイトがあるかどうかを確認します。その場合は、新しいバイトをバッファの末尾に追加して移動してください。それ以外の場合は、できるだけ多くのバイトをクライアントのソケットに送信し、送信が失敗してWSAEWOULDBLOCKエラーが発生した場合は、未送信のバイトをバッファの末尾に追加します。 TServerSocket.OnClientWriteイベントを使用して、バッファから未送信のデータの送信を終了し、送信されたバイトをバッファの先頭から削除します。

+0

返信ありがとう私の尊敬レミーと遅れてごめんなさい...あなたに行くためのソースコードを残してください。 – Bravesaw

関連する問題