2016-10-14 6 views
0

私は学校のプロジェクトのためにマルチプレイヤーカーブ・ファーバーを作ろうとしています。今のところ、私はクライアントとサーバー間の接続と作業中のチャットボックスを持っています。私が理解できないことは、すべてのクライアントに接続されているクライアントの量を送信する方法です。これを行うことで、ゲームが正しい人数を待つことを確かめることができます。私はまた、クライアントからサーバにデータを継続的に送信する方法を理解することができません。だから私はすべての選手からすべての座標を見ることができます。整数をクライアントに連続して送信するにはどうすればよいですか?そして、クライアントに接続しているクライアントの量をどのように送っていますか?

これが私のサーバーです:

public class Server 
{ 
    public TcpListener Listener; 
    private volatile bool Running; //wordt gebruikt door meerdere threads zonder lock te gebruiken (lock zorgt ervoor dat een thread niet doorgaat naar belangrijke code terwjil een andere thread nog bezig is om naar de locked code te gaan. 
    private List<BinaryWriter> writers = new List<BinaryWriter>(); 
    public Server(int port) 
    { 
     Listener = new TcpListener(IPAddress.Any, port); 
    } 

    public void Start() 
    { 
     Listener.Start(10); 
     Running = true; 

     while (Running) 
     { 
      var connection = Listener.AcceptTcpClient(); 
      ProcessConnection(connection);//Het zal asynchroon werken, omdat we nog niet eerder een beroep hebben geschreven af te wachten 
     } 
    } 


    public async Task ProcessConnection(TcpClient connection) 
    { //Het zal worden uitgevoerd in een afzonderlijke thread 
     var writer = new BinaryWriter(connection.GetStream()); 

     lock (writers) 
     { 
      writers.Add(writer); 
     } 

     using (var stream = new BinaryReader(connection.GetStream())) 
     { 
      //loop 
      while (Running && connection.Connected) 
      { 
       await Task.Factory.StartNew(() => { 
        var count = stream.ReadInt32(); 
        var data = stream.ReadBytes(count); 
        ProcessCommand(connection, writer, data); 
       }); 
      } 
      connection.Close(); 
     } 
     lock (writers) 
     { 
      writers.Remove(writer); 
     } 
    } 


    private void ProcessCommand(TcpClient connection, BinaryWriter writer, byte[] data) 
    { 
     var info = connection.Client.RemoteEndPoint as IPEndPoint; 
     var line = System.Text.Encoding.ASCII.GetString(data); 
     var response = String.Format("{1}:{2}: {0}", line, info.Address.ToString(), info.Port); 
     Console.WriteLine(response); 
     lock (writers) 
     { 
      foreach (var w in writers) 
      { 
       if (w != null) 
       { 
        try 
        { 
         w.Write((Int32)data.Length); 
         w.Write(data); 
         w.Flush(); 
        } 
        catch 
        { 

        } 
       } 
      } 
     } 
    } 


    public void Stop() 
    { 
     Running = false; 
     Listener.Stop(); 
    } 
    ~Server() 
    { 
     Running = false; 
     Listener.Stop(); 
    } 
} 

Andt彼は私のクライアントです:

 public async Task Start(int port) 
    { 

     Connection.Connect("localhost", port); 
     Console.WriteLine("Connected"); 
     Running = true; 
     Writer = new BinaryWriter(Connection.GetStream()); 

     using (var stream = new BinaryReader(Connection.GetStream())) 
     { 
      //infinite loop 
      while (Running && Connection.Connected) 
      { 
       await Task.Factory.StartNew(() => { 
        var count = stream.ReadInt32(); 
        var data = stream.ReadBytes(count); 
        ProcessCommand(data); 
       }); 
      } 
      Stop(); 
     } 
    } 
    //send data voor chat 
    public async Task Send(String line) 
    { 
     if (Writer == null) 
      return; 
     await Task.Factory.StartNew(() => { 
      var data = System.Text.Encoding.ASCII.GetBytes(line); 
      Writer.Write((Int32)data.Length); 
      Writer.Write(data); 
      Writer.Flush(); 
     }); 
    } 
    //krijg het aantal spelers connected 

    private void ProcessCommand(byte[] data) 
    { 
     var line = System.Text.Encoding.ASCII.GetString(data); 
     Console.WriteLine(line); 
     //stuur data van server naar method 
     textboxChat(line); 
    } 

    public void Stop() 
    { 
     Running = false; 
     Writer.Close(); 
     Writer = null; 
     Connection.Close(); 

    } 
    ~GamePlay() 
    { 
     Stop(); 
    } 

答えて

0

第一のポイント:接続されたクライアントの数:

サーバー側:

作成接続されたクライアントに関する情報を格納する辞書です。 私は個人的に、クライアントIP(またはあなたが持っている他の身分証明書)をキーとして使用し、クライアントデータは値(最後の接続のタイムスタンプ、クライアント座標など)として使用します。

この新しい辞書を更新するたびに、クライアントが新しいデータを切断または送信するたびに、または最後の操作が古すぎる場合は、この辞書を更新する必要があります。

このように、クライアントにデータを送信する場合、接続されたすべてのクライアントの数としてDictionary.KeyValuePairの数を送信できます。

このデータをすべて管理する準備が整ったら、クライアントとサーバーとの間でデータを送受信する必要があります。 これを行うには、両方向でメッセージを送信できることを確認してください。

第2ポイント:クライアントとサーバーの間でデータを連続的に送信します。

クライアント側: *メインループ内:データとともにメッセージを送信します。

  • サーバーからデータを受け取った場合://データを使用して任意の操作を行います。

サーバー側: *クライアントからデータを受信した場合:辞書のデータを更新してから、他の既知のクライアントに送信します。

これは私がやる方法です。 - サーバーがクライアントからデータを受信すると、彼はすべてのクライアントのすべてのデータで応答します。

関連する問題