2017-08-14 182 views
0

我建立一个客户机/服务器应用程序来学习如何游戏基于客户机/服务器的作品,但应用程序似乎不能很好地工作,这里是我的问题:如何正确构建客户端/服务器应用程序?

  1. 为什么不能这样应用程序可以” t关闭客户端应用程序时写入“播放器XXX离开”
  2. 如何正确接收来自服务器的数据? (我想接收来自服务器的位置信息,以使其在客户端)

这里是全码:

服务器:

public class ServerApp 
{ 
    public class Point 
    { 
     public int x; 
     public int y; 
    } 

    TcpListener listener; 
    List<Player> players; 

    string[,] data = new string[20, 40]; 

    public ServerApp() 
    { 
     players = new List<Player>(); 
    } 

    void PlayerJoin(TcpClient client) 
    { 
     lock (data) 
     { 
      if (data[0, 0] == "*") 
      { 
       data[0, 0] = "O"; 
       Player player = new Player(); 
       player.Entity = "O"; 
       player.Location = new Vector2(0,0); 
       player.Client = client; 
       players.Add(player); 
      } 
      else if (data[0, 39] == "*") 
      { 
       data[0, 40] = "P"; 
       Player player = new Player(); 
       player.Entity = "P"; 
       player.Location = new Vector2(0, 0); 
       player.Client = client; 
       players.Add(player); 
      } 
      else if (data[19, 0] == "*") 
      { 
       data[20, 0] = "I"; 
       Player player = new Player(); 
       player.Entity = "I"; 
       player.Location = new Vector2(0, 0); 
       player.Client = client; 
       players.Add(player); 
      } 
      else if (data[19, 39] == "*") 
      { 
       data[20, 40] = "U"; 
       Player player = new Player(); 
       player.Entity = "U"; 
       player.Location = new Vector2(0, 0); 
       player.Client = client; 
       players.Add(player); 
      } 
     } 
    } 

    void InitData(ref string[,] data) 
    { 
     for (int i = 0; i < 20; i++) 
     { 
      for (int j = 0; j < 40; j++) 
      { 
       if (i != 0 && i != 19) 
       { 
        if (j != 0 && j != 39) 
        { 
         data[i, j] = " "; 
        } 
        else 
        { 
         data[i, j] = "*"; 
        } 
       } 
       else 
       { 
        data[i, j] = "*"; 
       } 
      } 
     } 
    } 

    void InitServer() 
    { 
     listener = new TcpListener(new IPAddress(new byte[] { 127, 0, 0, 1 }), 6666); 
     listener.Start(); 
    } 

    void SyncDataToAllClient() 
    { 
     foreach (var player in players) 
     { 
      StreamWriter sw = new StreamWriter(player.Client.GetStream()); 
      int[] pos = new int[2]; 
      pos[0] = player.Location.x; 
      pos[1] = player.Location.y; 
      sw.Write(pos[0]); 
      sw.Write(pos[1]); 
      sw.Close(); 
     } 
    } 

    public void Run() 
    { 
     InitServer(); 
     InitData(ref data); 

     while (true) 
     { 
      if(listener.pending()) 
      { 
      var myclient = listener.AcceptTcpClient(); 
      if (myclient != null) 
      { 
       Console.WriteLine(string.Format("Client from {0} connected!", ((IPEndPoint)myclient.Client.RemoteEndPoint).Address)); 
       PlayerJoin(myclient); 

       Thread.Sleep(1000 * 5); 

       StreamWriter sw = new StreamWriter(myclient.GetStream()); 
       sw.Write(data); 
      } 
      CheckClient(); 
      SyncDataToAllClient(); 
      } 
     } 
    } 

    private void CheckClient() 
    { 
     foreach (var p in players) 
     { 
      if (!p.Client.Connected) 
      { 
       Console.WriteLine("Player {0} leave!", ((IPEndPoint)p.Client.Client.RemoteEndPoint).Address); 
       players.Remove(p); 
       data[p.Location.y, p.Location.x] = "*"; 
      } 
     } 
    } 
} 

客户:

public class ClientApp 
{ 
    TcpClient client; 

    string[,] data = new string[20, 40]; 
    bool quit; 
    public void Run() 
    { 
     EstablishConntionToServer(); 
     InitData(ref data); 
     while (!quit) 
     { 
      SyncDataFromServer(ref data); 
      PrintData(data); 
     } 
    } 

    void EstablishConntionToServer() 
    { 
     client = new TcpClient(); 
     client.Connect(new IPAddress(new byte[] { 127, 0, 0, 1 }), 6666); 
    } 

    void SyncDataFromServer(ref string[,] data) 
    { 
     Stream s = client.GetStream(); 
     char[] buffer=new char[1]; 
     StreamReader sr = new StreamReader(s); 
     sr.Read(buffer,0,1); 
    } 

    void InitData(ref string[,] data) 
    { 
     for (int i = 0; i < 20; i++) 
     { 
      for (int j = 0; j < 40; j++) 
      { 
       //data[i, j] = "*"; 
       if (i != 0 && i != 19) 
       { 
        if (j != 0 && j != 39) 
        { 
         data[i, j] = " "; 
        } 
        else 
        { 
         data[i, j] = "*"; 
        } 
       } 
       else 
       { 
        data[i, j] = "*"; 
       } 
      } 
     } 
    } 

    void PrintData(string[,] data) 
    { 
     Console.Clear(); 
     for (int i = 0; i < 20; i++) 
     { 
      for (int j = 0; j < 40; j++) 
      { 
       Console.Write(data[i, j]); 
      } 
      Console.Write(Environment.NewLine); 
     } 

     System.Threading.Thread.Sleep(500); 
    } 
} 
+0

我*假设你的意思是“客户/服务器”的“C/S”?这部分问题严重隐含,但从未明确阐述。 –

+1

你的问题太广泛了。对最简单部分的简短回答:您无法检查客户端状态,因为您的代码卡在'AcceptTcpClient()'调用中。你会看到,如果你使用调试器来看看代码在做什么。解决这类问题的常用方法是编写异步代码,以便在网络I/O事件发生时响应,而不会阻止任何一个线程响应。我在最近发布的[这个答案](https://stackoverflow.com/a/44942011)中有一个例子。 –

回答

0

解决方案:

对于传输客户端运动w ith服务器,你会想要使用UDP的速度。这是经常在游戏中传输数据的最有效方式。

至于你的其他问题,它最有可能不知道客户端,可能你的连接没有被正确关闭,因此连接必须超时才能被识别为关闭。

相关问题