Socket之简单的Unity3D聊天室__TCP协议
服务器端程序
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net; 5 using System.Net.Sockets; 6 using System.Text; 7 using System.Threading.Tasks; 8 namespace 聊天室_服务器端_TCP 9 { 10 class Program 11 { 12 //存放客户端 13 static List<Client> clientList = new List<Client>(); 14 15 //广播消息 16 public static void BroadCastMessage(string message) 17 { 18 //创建未连接的list 19 var notConnectedList = new List<Client>(); 20 foreach(Client client in clientList) 21 { 22 if (client.Connected) //给所有连接的客户端发送消息; 23 client.SendMessage(message); 24 else //把未连接的客户端加入list 25 { 26 notConnectedList.Add(client); 27 } 28 } 29 //移除未连接的客户端 30 foreach(var temp in notConnectedList) 31 { 32 clientList.Remove(temp); 33 } 34 } 35 36 static void Main(string[] args) 37 { 38 //实例化服务器端Socket并指定IP地址类型(IPV4),套接字类型(流类型),通信协议(TCP) 39 Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 40 41 //绑定终端(设置IP地址,端口号(范围为0-65535之间随意取,为避免端口号已被其他软件占用,可以取大点)) 42 tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.107"), 7788)); 43 44 //开始监听,等待客户端接入,接入后执行后续操作 45 tcpServer.Listen(100); 46 Console.WriteLine("开始监听"); 47 48 //循环等待客户端接入 49 while (true) 50 { 51 52 Socket ClientSocket = tcpServer.Accept(); 53 Console.WriteLine("一个客户端连接进来了"); 54 Client client = new Client(ClientSocket); 55 clientList.Add(client); 56 } 57 58 } 59 } 60 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net.Sockets; 5 using System.Text; 6 using System.Threading; 7 using System.Threading.Tasks; 8 9 namespace 聊天室_服务器端_TCP 10 { 11 public class Client 12 { 13 private Socket clientsocket; 14 private Thread t; //线程 15 private byte[] data = new byte[1024]; 16 public Client(Socket s) 17 { 18 this.clientsocket = s; 19 20 //启动一个线程,处理客户端数据接收 21 t = new Thread(ReceiveMessage); 22 t.Start(); 23 } 24 25 private void ReceiveMessage() 26 { 27 //一直接收客户端数据 28 while(true) 29 { 30 if(clientsocket.Poll(10,SelectMode.SelectRead)) 31 { 32 clientsocket.Close(); 33 break; 34 } 35 int length= clientsocket.Receive(data); 36 string message = Encoding.UTF8.GetString(data, 0, length); 37 //接收到数据时,要把这个数据分发到客户端 38 //广播消息 39 Program.BroadCastMessage(message); 40 Console.WriteLine("收到消息:" + message); 41 } 42 } 43 44 //发送消息给客户端 45 public void SendMessage(string message) 46 { 47 byte[] data = Encoding.UTF8.GetBytes(message); 48 clientsocket.Send(data); 49 } 50 51 //判断是否连接 52 public bool Connected 53 { 54 get { return clientsocket.Connected; } 55 } 56 } 57 }
客户端
1 using System.Collections; 2 using System.Collections.Generic; 3 using System.Net.Sockets; 4 using UnityEngine; 5 using System.Net; 6 using System.Text; 7 using UnityEngine.UI; 8 using System.Threading; 9 10 public class ChatManger : MonoBehaviour { 11 12 public string ipaddress = "192.168.0.107"; 13 public int port = 7788; 14 public Text Input; //InputField中显示输入的text 15 public Text Label; //聊天室显示的text 16 17 private Socket client_socket; 18 private Thread t; 19 private byte[] data = new byte[1024]; //数据容器 20 private string message = ""; //消息容器 21 // Use this for initialization 22 void Start () { 23 OnConnectedToServer(); 24 } 25 26 // Update is called once per frame 27 void Update () { 28 if(message!=""&&message!=null) 29 { 30 Label.text += "\n" + message; 31 message = ""; 32 } 33 } 34 35 //连接至服务器,并创建一个新线程用于接受消息 36 public void OnConnectedToServer() 37 { 38 client_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 39 client_socket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress),port)); 40 41 t = new Thread(ReceiveMessage); 42 t.Start(); 43 } 44 45 //接收消息 46 public void ReceiveMessage() 47 { 48 while(true) 49 { 50 if (client_socket.Poll(10, SelectMode.SelectRead)) 51 { 52 client_socket.Close(); 53 break; 54 } 55 int length = client_socket.Receive(data); 56 message = Encoding.UTF8.GetString(data, 0, length); 57 //Label.text += "\n" + message; unity不允许在单独的线程里去操控其组件 58 } 59 } 60 //发送消息 61 public new void SendMessage(string message) 62 { 63 byte[] data = Encoding.UTF8.GetBytes(message); 64 client_socket.Send(data); 65 } 66 //点击发送按钮 67 public void OnSendButtonClick() 68 { 69 70 SendMessage(Input.text); 71 Input.GetComponentInParent<InputField>().text = ""; 72 } 73 74 //当Mono被销毁时调用此方法 75 private void OnDestroy() 76 { 77 client_socket.Shutdown(SocketShutdown.Both); 78 client_socket.Close(); 79 } 80 }