4.基于TCP协议的unity聊天室Demo
1.服务器一般都是买的服务器地址。这里我们用第一节VS写的服务器模拟;
如果从第一节做下来的,直接启动TCP服务器就行了。
否则打开VS,新建控制台应用,把上面第一节的代码复制粘贴上去,启动服务器。
如果启动成功是这样的画面:
2.接下来我们用Unity做一个聊天室客户端
打开Unity,新建一个项目,项目名字UnityClient(其他名字也行)
新建一个c#脚本。名字就Client,完整代码如下
using System;
using System.Collections;
using System.Collections.Generic;
usingSystem.Net;
usingSystem.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;
public class Client : MonoBehaviour {
//这里填要连接的ip
private string ip = "10.198.1.15";
//这里填端口号
private int port = 9900;
public InputField Name_inputField;
public Text ConnectText;
public InputField chat_inputField;
public Text ChatText;
private Socket ClientSocket;
private String TmpMessage = null;
// 更新并显示接收的数据
private void Update()
{
if (TmpMessage != null)
{
ChatText.text += System.Environment.NewLine+ TmpMessage;
//+ TmpMessage;
TmpMessage = null;
}
}
//这里我们不自动连接服务器,写一个方法用来连接服务器
public void Connect()
{
if (Name_inputField.text == "")
{
ConnectText.text = "连接服务器失败,请输入用户名";
}
else
{
try
{
//创建Socket
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//连接服务器
ClientSocket.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
Thread t = new Thread(ReceiveMessage);
t.Start();
//把自己的名字发送给服务器
SendMsg(Name_inputField.text);
//Debug.LogError(Name_inputField.text);
ShowMessage("连接服务器成功");
}
catch (Exception e)
{
//捕捉异常并显示
ShowMessage("服务器未启动或ip地址错误");
}
}
}
//这个方法用来显示提示信息
private void ShowMessage(string msg)
{
ConnectText.text = msg;
}
//这是封装的一个发送消息的方法,传入一个字符串就可以发给服务器了
private void SendMsg(string msg)
{
try
{
byte[] SendData = Encoding.UTF8.GetBytes(msg);
ClientSocket.Send(SendData);
}
catch (Exception e)
{
Debug.LogError(e.ToString());
ShowMessage("消息发送失败");
}
}
//这个方法是给发送按钮调用的方法
public void SendButtonFunc()
{
//把输入框的字符串发给服务器
SendMsg(chat_inputField.text);
//输入框清空
chat_inputField.text = "";
}
//这是用来接收消息的方法
private void ReceiveMessage()
{
//用一个while循环不停的接收
while (true)
{
//判断一下,如果连接断开了就不接收了
if (ClientSocket.Connected == false)
{
break;
}
//接收服务端的消息
byte[] ReceivedData = new byte[1024];
int length = ClientSocket.Receive(ReceivedData);
string ReceivedMessage = Encoding.UTF8.GetString(ReceivedData, 0, length);
Debug.LogError(ReceivedMessage);
TmpMessage = ReceivedMessage;
}
}
private void OnApplicationQuit()
{
ClientSocket.Shutdown(SocketShutdown.Both);
ClientSocket.Close();
}
}
接下来绑定按钮的方法和添加组件:
按名字拖进去:
找到按钮,添加方法:
发送按钮 :
连接服务器按钮:
客户端的工作就做完了
服务器的代码要做小小的改动。因为加入了客户端的名字功能:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
usingSystem.Net;
usingSystem.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;
namespace TCP_Sever
{
class ClientedSocket
{
//填加了一个用户名字的是有变量
private String UserName = null;
private Socket clientedSocket;
private Thread t;
private byte[] ReceivedData = new byte[1024];
public ClientedSocket(Socket ClientedSocket)
{
this.clientedSocket = ClientedSocket;
//启动一个线程,处理客户端的数据接收
t = new Thread(ReceiveMessage);
t.Start();
}
private void ReceiveMessage()
{
try
{
//一直接收
while (true)
{
//在接收数据之前 判断一下Socket连接是否断开
if (clientedSocket.Poll(10, SelectMode.SelectRead))
{
Console.WriteLine("断开连接");
clientedSocket.Shutdown(SocketShutdown.Both);
clientedSocket.Close();
break;
}
int length = clientedSocket.Receive(ReceivedData);
string ReceivedMessage = Encoding.UTF8.GetString(ReceivedData, 0, length);
//当用户名为空时,给用户名赋值
if (UserName==null)
{
UserName = ReceivedMessage;
Console.WriteLine("Client setName:"+ UserName);
}
//不为空就广播消息
else
{
string msg = UserName + ":" + ReceivedMessage;
Console.WriteLine(msg);
//数据分发:
Program.BroadCastMessage(msg);
}
}
}
catch(Exception e)
{
Console.WriteLine(e);
clientedSocket.Shutdown(SocketShutdown.Both);
clientedSocket.Close();
}
}
public void SendMessage(string msg)
{
byte[] SendData = Encoding.UTF8.GetBytes(msg);
clientedSocket.Send(SendData);
}
public bool Connect()
{
return clientedSocket.Connected;
}
}
}
build客户端。启动服务器,运行两次客户端程序,就可以两个客户端互相通信了