Unity 简易聊天室(基于TCP)(1)

为了准备毕业设计,学习了服务器与客户端之间传输的一些简单的知识,并跟着网络上的教程制作了一个简易的Unity聊天室

服务器:用C# .Net Framework写的

结构分为:main(主函数)、Server类(用于服务器的开启和接收客户端连接)、Client类(接收消息和发送消息)、Message类(用于消息的解析和包装)

main:

static void Main(string[] args)
{
  string ip = "127.0.0.1";  //这个ip地址表示本机
  int port = 6688;  //测试用的端口号,应该可以自己随便写吧
  Server server = new Server(ip, port);
  server.Start();


  Console.ReadKey();
}

Server:

public class Server
{
  private Socket serverSocket = null;
  private List<Client> clientList = new List<Client>();
  private Socket clientSocket = null;


  public Server() { }

  public Server(string ip,int port)
  {

         //创建socket,然后绑定ip地址和端口号

    //传输类型是流,使用的协议是Tcp
    serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    EndPoint point = new IPEndPoint(IPAddress.Parse(ip), port);
    serverSocket.Bind(point);
  }

  public void Start()
  {
    serverSocket.Listen(0);   //开始监听  0表示等待连接队列的最大数
    Console.WriteLine("开始监听");
    Console.WriteLine("等待客户端连接");
    serverSocket.BeginAccept(AcceptCallBack, null); //等待客户端连接,AcceptCallBack是回调,第三个参数目前还没用过,没去了解作用  TODO
  }

  private void AcceptCallBack(IAsyncResult ar)
  {
    clientSocket = serverSocket.EndAccept(ar);
    Console.WriteLine("一个客户端连接");
    Client client = new Client(clientSocket,this);  //当客户端连接上后,用Client类处理消息的接收与发送
    clientList.Add(client);
    client.Start();//开始接收消息

    serverSocket.BeginAccept(AcceptCallBack, null);  //服务器继续等待其他客户端连接
  }

  

  public void Broadcast(string message)  //广播消息
  {
    foreach(Client client in clientList)
    {
      client.SendMessage(message);
    }
  }
}

 

Client:

 

public class Client
{
  private Socket clientSocket;
  private Server server;
  private Message msg = new Message();

  public Client() { }

  public Client(Socket clientSocket,Server server)
  {
    this.clientSocket = clientSocket;
    this.server = server;
  }


  public void Start()
  {
    //判断客户端是否被关闭  
    if (clientSocket.Connected == false || clientSocket.Poll(10, SelectMode.SelectRead))
    {
      clientSocket.Close();
      return;
    }

    //等待从客户端的消息的接收
    clientSocket.BeginReceive(msg.data, 0, msg.data.Length, SocketFlags.None, ReceiveCallBack, null);
  }


  private void ReceiveCallBack(IAsyncResult ar)
  {
  try
  {

    //需要用try catch 捕捉异常,不然出现异常服务器会终止
    //判断客户端是否被关闭
    if (clientSocket.Connected==false || clientSocket.Poll(10,SelectMode.SelectRead))
    {
      clientSocket.Close();
      return;
    }

    int len = clientSocket.EndReceive(ar);  //返回的len表示接收的数据长度
    if (len == 0) //客户端被关闭了 服务端会接收到0字节的消息
    {
      clientSocket.Close();
      return;
    }

    msg.Read(len, OnProessMassage);//Message类解析消息
    //Console.WriteLine("receive:" + message);

    clientSocket.BeginReceive(msg.data, 0, msg.data.Length, SocketFlags.None, ReceiveCallBack, null);
  }
  catch (Exception e)
  {
    Console.WriteLine("ReceiveCallBack:" + e);
  }

  }

  private void OnProessMassage(string msg)
  {
    server.Broadcast(msg);//通过服务器广播消息
  }


  public void SendMessage(string message)
  {
    //判断客户端是否被关闭  发送的时候客户端也可能被关闭
    if (clientSocket.Connected == false || clientSocket.Poll(10, SelectMode.SelectRead))
  {
    clientSocket.Close();
    return;
  }

  clientSocket.Send(msg.Pack(message)); //发送消息给客户端
  //Console.WriteLine("send:"+message);
  }

}

Message:

 //这里只是简单的处理消息;解析:从byte[] ->string;发送:string->byte[]

class Message
{

  public byte[] data = new byte[1024];

  public void Read(int len,Action<string>OnProessMessage)
  {
    string message = Encoding.UTF8.GetString(data, 0, len);
    OnProessMessage(message);
    Array.Clear(data, 0, len);
  }


  public byte[] Pack(string msg)
  {
    byte[] dataBytes = Encoding.UTF8.GetBytes(msg);
    return dataBytes;
  }  

}

猜你喜欢

转载自www.cnblogs.com/darkif/p/10072160.html