**

学习TCP/IP协议之socket编程——用C#和Unity模拟聊天室案例

本人最近在学C#的TCP/IP协议,因此将学习的地方做一个博客进行记录和总结,有兴趣的朋友也可以来看下,学习tcp和ip协议及网络编程技术可以系统地了解了TCP/IP协议族的体系结构,还有IP层、传输层和应用层中各种协议的具体原理和工作机制,还可以学习基于socket编程接口的网络编程技术,重点学习客户端和服务器端编程应注意的问题、可用的模式和技术。做到理论联系实际,能有效提高对TCP/IP的理解和网络开发能力。

unity虚拟偶像捏脸技术_unity3d


一、简单的发送消息给客户端的案例

一、服务端的创建

//1创建socket并导入命名空间
 socket是using System.Net.Sockets;命名空间下
 Socket tcpServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
 //2绑定ip跟端口号(ip在win+R中输入cmd后输入ipconfig查询)
 IPAddress ipaddress=new IPAddress(new byte[]{192,168,0,103});
 EndPoint point =new IPEndPoint(ipaddress,7788);//ipendponit是对ip加端口做了一层封装的类
 tcpServer.Bind(point);//向操作系统申请一个可用的ip跟端口号用来通信
 //3开始监听(等待客户端连接)
 tcpServer.Listen(100);//此参数表示最大连接数
 Socket clientSocket = tcpServer.Accept();//暂停当前线程,直到有一个客户端连接过来,使用返回的clientSocket做通信
 string message = “Hello 欢迎你”;
 byte[] data = EnCoding.UTF8.GetBytes(message);//对字符串做编码,得到一个字符串的字节数组
 clientSocket.Send(data);//发送给客户端

二、客户端的创建

//1创建socket
 Socket tcpServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
 //2.发起建立连接的请求
 IPAddress ipaddress=ipaddress.Parse(“192,168,0,103”);//可以把一个字符串的ip地址转换为IPAddress对象
 EndPoint point =new IPEndPoint(ipaddress,7788);
 tcpClient.Connect(point);//通过ip:端口号定位到一个要连接到的服务器端
 byte[] data =new byte[1024];
 int length = tcpClient.Receive(data);//这里传递一个byte数组,实际上这个data数组用来接收数据,length返回值表示接收了多少字节的数据
 string message = EnCoding.UTF8.GetString(data,0,length);//只把需要接收到的数据做转换
 Console.WriteLine(message);

二、进阶篇使用TCP/IP协议socket编程模拟聊天室案例

一.开发建立连接的代码

//自定义的Client类
 class Client
 {
 private Socket clientSocket;
 public Client(Socket s)//构造Client方法
 {
 clientSocket=s;
 }
 }
 //在服务器端类中定义一个Client数组,储存与客户端连接的Client类
 static List clientList=new List();
 Socket tcpServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
 tcperver.Bind(new IPEndPoint(ipaddress.Parse(“192,168,0,103”),7788));
 tcpServer.Listen(100);
 while(true)//死循环不断检测有无新的客户端连接
 {
 Socket clientSocket = tcpServer.Accept();
 Client client = new Client(clientSocket);//把与每个客户端通信的逻辑放到我们自定义的Client类里
 clientList.Add(client);
 }
 //创建Unity客户端,打开unity在一个空物体上挂载一个管理聊天的脚本,命名为CharManager
 public string ipaddress=“192,168,0,103”;
 public int port =7788;
 public UIIput textInput;
 private Socket clientSocket;
 void Start(){
 ConnetToServer();
 }
 void ConnetToServer(){
 clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
 //创建后与服务器建立连接
 clientSocket.Connent(new IPEndPoint(ipaddress.Parse(“192,168,0,103”),7788));
 }


根据以上代码完成建立连接,接下来进行数据的发送。

二、客户端发送消息给服务器端

在CharManager中提供发送消息方法和Onclick点击事件方法
 void SendMessage(string message){
 byte[] data = Encoding.UTF8.GetBytes(message);
 clientSocket.Send(data);
 }
 public void OnSendButtonOnClick(){
 string value =textInput.value;
 SendMessage(value);
 textInput.value="";//发送完消息后输入框的字段清空
 }
 void OnDestory(){
 clientSocket.ShutDown(SocketShutDown.both);//关闭连接,SocketShutDown为枚举类型,可以选择断开接收还是断开发送或者所有都断开。
 clientSocket.Close();
 }
代码编译完成后,将点击事件注册到按钮,同时把textInput赋值,接下来完成对消息的接收,由于我们接收消息有自定义的类Client完成的,因此我们继续对该类进行开发
 //启动一个线程处理客户端的数据接收
 先定义一个线程变量和一个byte数组作为存储数据的变量
 private Thread t;
 private byte[] data=new byte[1024];
 public Client(Socket s)
 {
 clientSocket=s;
 t= new Thread(ReceiveMessage);
 t.Start();
 }
 //在Clinet类中添加一个发送消息方法
 public void SendMessage(string message){
 byte[] data = Encoding.UTF8.GetBytes(message);
 clientSocket.Send(data);
 }
 private void ReceiveMessage(){
 //一直接收客户端的数据
 while(true){
 //在接收数据前要判断socket是否断开
 if(clientSocket.Poll(10,SelectMode.SelectRead)){//Poll方法第一个参数代表超时时间,第二个方法代表能否在客户端读到东西,如果连接关闭重置或终止则返回true
 clientSocket.Close();
 break;//如果是断开的则跳出循环,终止线程的执行
 }
 int length = clientSocket.Receive(data);
 string massage =Encoding.UTF8.GetString(data,0,length);
 Console.writeLine(“收到了消息:”+message);//测试代码,测试成功后将接收到数据后把这个数据分发到所有客户端
 }
 }

三、在服务器端广播消息到所有客户端

在服务器端添加一个广播方法,并在client类中广播出去
在每个client中定义一个属性,检测是否是连接着的

public bool Connented{get{return clientSocketed;}}
 public static void BroadcastMessage(string message){
 //广播中便利我们的clientList集合,让每个client都调用自身的SendMessage方法
 foreach (var client in clientList){
 var notConnentedList = new List();
 if(client.Connented)
 client.SendMessage(message);
 else
 notConnentedList.Add(client);
 }
 foreach(var temp in notConnentedList){
 clientList.Remove(temp);//将断开连接的client都移除
 }
 }
 //我们在client类中将测试代码修改为我们的广播方法
 ProgramBroadcastMessage( message);


接下来我们继续是在客户端上完成接收消息的方法内容和客户端相似就不重复演示了