Tcp多人聊天C#,Unity实现
C#模拟服务器,Unity模拟客户端
效果图:
思路:客户端连接服务器发送上线消息,服务器记录所有user,然后广播给已经在线的玩家,同时发送所有玩家的名字给上线的用户,实现同步好友列表,这里用的是PopList制作的用户列表,更新显示上线消息的,这用的是TextList(NGUI制作的UI),在客户端异步发送环节,并没有在messagecenter中写派发发送消息的方法,因为懒呗,只写了一个派发收到消息的函数,通过收到消息中的协议的协议号处理消息,这里我用的协议是协议号(ushort)+消息的长度(ushort)+消息的内容(byte[]),也就是MessagePackage的一个实例,发送的时候把三个字段转成byte数组进行拼接发送,在MyTools工具类定义的就是操作数据的方法,那么服务器的流程也是和客户端一样的结构,不一样的就是具体的消息操作类逻辑
主要类:
客户端:
UITalkController:这个是挂在类,用来显示消息,和交互服务器连接
Client:封装套接字客户端Socket,用来与服务器通讯,包含,连接,断开,发送,接受等方法
IMessage:消息处理类的接口
MessageCenter:消息中心
OnLineState:上线信息的具体操作类
TalkState:聊天消息的具体操作类
TalkMessage:消息的包(protobuf工具生成,此类主要是承载通讯的消息,通过protobuf进行序列化与反序列化)
MessagePackage:发送和接受的包
MyTools:工具类,主要方法,封包,分包,序列化,反序列化
服务器:
Program:主函数,用于开启服务器Server:封装服务器套接字,用于通讯
MyTools:工具类,主要方法,封包,分包,序列化,反序列化
IMessage:消息处理类的接口
MessageCenter:消息中心
OnLineState:上线信息的具体操作类
TalkState:聊天消息的具体操作类
TalkMessage:消息的包(protobuf工具生成,此类主要是承载通讯的消息,通过protobuf进行序列化与反序列化)
在编写的过程发现IMessage,MessageCenter,MyTools,TalkMessage,MessagePackage是通用的,原理基本都是一样的,下面贴出代码:
客户端:
挂载类:
using System.Collections.Generic;
using UnityEngine;
using day1_7MessageData;
using System.Text;
using Day1_7EVEServer;
public class UITalkController : MonoBehaviour {
//用户列表
public UIPopupList userPopList;
//消息输入框
public UIInput ipInput;
public UIInput portInput;
public UIInput messageInput;
public UIInput nickNameInput;
//消息显示文本
public UITextList textList;
public UIButton sendBtn;
public UIButton clearBtn;
public UIButton connectBtn;
public UIButton disConnectBtn;
public UIButton reConnectBtn;
// Use this for initialization
void Start () {
userPopList.AddItem("所有人");
//按钮注册事件,两种方式
sendBtn.onClick.Add(new EventDelegate(SendBtnHandler));
clearBtn.onClick.Add(new EventDelegate(ClearBtnHandler));
connectBtn.onClick.Add(new EventDelegate(ConnectBtnHandler));
UIEventListener.Get(disConnectBtn.gameObject).onClick += DisConnectBtnHandler;
UIEventListener.Get(reConnectBtn.gameObject).onClick += ReConnectBtnHandler;
}
/// <summary>
/// 上线用户添加方法
/// </summary>
private void UserFun()
{
List<string> list = userPopList.items;
for (int i = 0; i < MessageCenter.Instance.userList.Count; i++)
{
if (!list.Contains(MessageCenter.Instance.userList[i]))
{
userPopList.AddItem(MessageCenter.Instance.userList[i]);
}
}
}
/// 重新连接服务器
private void ReConnectBtnHandler(GameObject go)
{
Client.Instance.ReConnectToServer(ipInput.value,int.Parse(portInput.value));
}
/// <summary>
/// 断开连接
/// </summary>
/// <param name="go"></param>
private void DisConnectBtnHandler(GameObject go)
{
Client.Instance.DisConnectToServer();
}
/// <summary>
/// 连接服务器按钮
/// </summary>
private void ConnectBtnHandler()
{
Client.Instance.StartClient();
bool isOnline=Client.Instance.ConnectToServer(ipInput.value, int.Parse(portInput.value));
if (isOnline) {
SendOnlineMessage();
}
}
/// <summary>
/// 清屏按钮
/// </summary>
private void ClearBtnHandler()
{
textList.Clear();
}
/// <summary>
/// 发送消息按钮
/// </summary>
private void SendBtnHandler()
{
MessagePackage mPackage = new MessagePackage();
mPackage.packageID = 1002;
TalkMessage talkMessage = new TalkMessage();
talkMessage.name = nickNameInput.value;
talkMessage.data = messageInput.value;
mPackage.protobufBytes = MyTools.Instance.ProtoBufSerialized<TalkMessage>(talkMessage);
Client.Instance.SendToServer(mPackage);
messageInput.value = "";
}
/// <summary>
/// 发送上线消息
/// </summary>
private void SendOnlineMessage()
{
MessagePackage mPackage = new MessagePackage();
mPackage.packageID = 1001;
TalkMessage talkMessage = new TalkMessage();
talkMessage.name = nickNameInput.value;
talkMessage.data = "上线了";
mPackage.protobufBytes = MyTools.Instance.ProtoBufSerialized<TalkMessage>(talkMessage);
Client.Instance.SendToServer(mPackage);
}
/// <summary>
/// 显示消息
/// </summary>
/// <param name="talkMessage"></param>
private void UpdateMessageLabel(TalkMessage talkMessage) {
StringBuilder sb = new StringBuilder();
sb.Append(talkMessage.name);
sb.Append("说:");
sb.Append(talkMessage.data);
textList.Add(sb.ToString());
}
void Update () {
//处理消息队列
if (MessageCenter.Instance.messageQueue.Count>0) {
TalkMessage talkMessage= MessageCenter.Instance.messageQueue.Dequeue();
UpdateMessageLabel(talkMessage);
}
//如果有上线的用户
if (MessageCenter.Instance.isAddUser)
{
UserFun();
PrintToConsole.Instance.PrintTo("当前的用户的数量:" + MessageCenter.Instance.userList.Count);
MessageCenter.Instance.isAddUser = false;
}
}
}
using UnityEngine;
using day1_7MessageData;
using System.Text;
using Day1_7EVEServer;
public class UITalkController : MonoBehaviour {
//用户列表
public UIPopupList userPopList;
//消息输入框
public UIInput ipInput;
public UIInput portInput;
public UIInput messageInput;
public UIInput nickNameInput;
//消息显示文本
public UITextList textList;
public UIButton sendBtn;
public UIButton clearBtn;
public UIButton connectBtn;
public UIButton disConnectBtn;
public UIButton reConnectBtn;
// Use this for initialization
void Start () {
userPopList.AddItem("所有人");
//按钮注册事件,两种方式
sendBtn.onClick.Add(new EventDelegate(SendBtnHandler));
clearBtn.onClick.Add(new EventDelegate(ClearBtnHandler));
connectBtn.onClick.Add(new EventDelegate(ConnectBtnHandler));
UIEventListener.Get(disConnectBtn.gameObject).onClick += DisConnectBtnHandler;
UIEventListener.Get(reConnectBtn.gameObject).onClick += ReConnectBtnHandler;
}
/// <summary>
/// 上线用户添加方法
/// </summary>
private void UserFun()
{
List<string> list = userPopList.items;
for (int i = 0; i < MessageCenter.Instance.userList.Count; i++)
{
if (!list.Contains(MessageCenter.Instance.userList[i]))
{
userPopList.AddItem(MessageCenter.Instance.userList[i]);
}
}
}
/// 重新连接服务器
private void ReConnectBtnHandler(GameObject go)
{
Client.Instance.ReConnectToServer(ipInput.value,int.Parse(portInput.value));
}
/// <summary>
/// 断开连接
/// </summary>
/// <param name="go"></param>
private void DisConnectBtnHandler(GameObject go)
{
Client.Instance.DisConnectToServer();
}
/// <summary>
/// 连接服务器按钮
/// </summary>
private void ConnectBtnHandler()
{
Client.Instance.StartClient();
bool isOnline=Client.Instance.ConnectToServer(ipInput.value, int.Parse(portInput.value));
if (isOnline) {
SendOnlineMessage();
}
}
/// <summary>
/// 清屏按钮
/// </summary>
private void ClearBtnHandler()
{
textList.Clear();
}
/// <summary>
/// 发送消息按钮
/// </summary>
private void SendBtnHandler()
{
MessagePackage mPackage = new MessagePackage();
mPackage.packageID = 1002;
TalkMessage talkMessage = new TalkMessage();
talkMessage.name = nickNameInput.value;
talkMessage.data = messageInput.value;
mPackage.protobufBytes = MyTools.Instance.ProtoBufSerialized<TalkMessage>(talkMessage);
Client.Instance.SendToServer(mPackage);
messageInput.value = "";
}
/// <summary>
/// 发送上线消息
/// </summary>
private void SendOnlineMessage()
{
MessagePackage mPackage = new MessagePackage();
mPackage.packageID = 1001;
TalkMessage talkMessage = new TalkMessage();
talkMessage.name = nickNameInput.value;
talkMessage.data = "上线了";
mPackage.protobufBytes = MyTools.Instance.ProtoBufSerialized<TalkMessage>(talkMessage);
Client.Instance.SendToServer(mPackage);
}
/// <summary>
/// 显示消息
/// </summary>
/// <param name="talkMessage"></param>
private void UpdateMessageLabel(TalkMessage talkMessage) {
StringBuilder sb = new StringBuilder();
sb.Append(talkMessage.name);
sb.Append("说:");
sb.Append(talkMessage.data);
textList.Add(sb.ToString());
}
void Update () {
//处理消息队列
if (MessageCenter.Instance.messageQueue.Count>0) {
TalkMessage talkMessage= MessageCenter.Instance.messageQueue.Dequeue();
UpdateMessageLabel(talkMessage);
}
//如果有上线的用户
if (MessageCenter.Instance.isAddUser)
{
UserFun();
PrintToConsole.Instance.PrintTo("当前的用户的数量:" + MessageCenter.Instance.userList.Count);
MessageCenter.Instance.isAddUser = false;
}
}
}
Client类
using System.Net;
using System.Net.Sockets;
using System;
using Day1_7EVEServer;
/// 客户端
public class Client : SingleTon<Client> {
public Socket clientSocket;
public IPEndPoint point;
public IPAddress ip;
public int port;
byte[] receiveBytes = new byte[1024];
public Client() {
}
/// 开启客户端
public void StartClient() {
}
/// 连接服务器
public bool ConnectToServer(string ip,int port) {
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
point = new IPEndPoint(IPAddress.Parse(ip), port);
clientSocket.Connect(point);
if (!clientSocket.Connected) {
PrintToConsole.Instance.PrintTo("连接服务器失败");
}
//开启异步接受消息
ReceiveFromServer();
return clientSocket.Connected;
}
/// 断开连接
public void DisConnectToServer()
{
//断开连接且允许重新连接
if (clientSocket!=null) {
clientSocket.Close();
}
}
/// 重新连接
public bool ReConnectToServer(string ip, int port)
{
if (clientSocket != null)
{
ConnectToServer( ip,port);
}
return clientSocket.Connected;
}
/// 发送消息
public void SendToServer(MessagePackage mPackage)
{
byte[] data = MyTools.Instance.BuilderPackage(mPackage);
if (clientSocket != null && clientSocket.Connected)
{
clientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, AsyncSend, null);
}
}
/// 异步发送回调
private void AsyncSend(IAsyncResult ar)
{
if (clientSocket != null)
{
int count=clientSocket.EndSend(ar);
}
}
/// 接受消息
public void ReceiveFromServer()
{
if (clientSocket!=null) {
clientSocket.BeginReceive(receiveBytes,0, receiveBytes.Length,SocketFlags.None,ReceiveCallBack,null);
}
}
/// 异步接受消息回调
private void ReceiveCallBack(IAsyncResult ar)
{
if (clientSocket!=null) {
int count=clientSocket.EndReceive(ar);
if (count <= 0)
{
//断开连接
DisConnectToServer();
}
else
{
// 拆包
byte[] data = new byte[count];
Buffer.BlockCopy(receiveBytes,0,data,0,count);
// messageQueue.Enqueue(talkmessage);
MessageCenter.Instance.DistributeMessage(clientSocket, data);
}
}
ReceiveFromServer();
}
}//End...
using System.Net.Sockets;
using System;
using Day1_7EVEServer;
/// 客户端
public class Client : SingleTon<Client> {
public Socket clientSocket;
public IPEndPoint point;
public IPAddress ip;
public int port;
byte[] receiveBytes = new byte[1024];
public Client() {
}
/// 开启客户端
public void StartClient() {
}
/// 连接服务器
public bool ConnectToServer(string ip,int port) {
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
point = new IPEndPoint(IPAddress.Parse(ip), port);
clientSocket.Connect(point);
if (!clientSocket.Connected) {
PrintToConsole.Instance.PrintTo("连接服务器失败");
}
//开启异步接受消息
ReceiveFromServer();
return clientSocket.Connected;
}
/// 断开连接
public void DisConnectToServer()
{
//断开连接且允许重新连接
if (clientSocket!=null) {
clientSocket.Close();
}
}
/// 重新连接
public bool ReConnectToServer(string ip, int port)
{
if (clientSocket != null)
{
ConnectToServer( ip,port);
}
return clientSocket.Connected;
}
/// 发送消息
public void SendToServer(MessagePackage mPackage)
{
byte[] data = MyTools.Instance.BuilderPackage(mPackage);
if (clientSocket != null && clientSocket.Connected)
{
clientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, AsyncSend, null);
}
}
/// 异步发送回调
private void AsyncSend(IAsyncResult ar)
{
if (clientSocket != null)
{
int count=clientSocket.EndSend(ar);
}
}
/// 接受消息
public void ReceiveFromServer()
{
if (clientSocket!=null) {
clientSocket.BeginReceive(receiveBytes,0, receiveBytes.Length,SocketFlags.None,ReceiveCallBack,null);
}
}
/// 异步接受消息回调
private void ReceiveCallBack(IAsyncResult ar)
{
if (clientSocket!=null) {
int count=clientSocket.EndReceive(ar);
if (count <= 0)
{
//断开连接
DisConnectToServer();
}
else
{
// 拆包
byte[] data = new byte[count];
Buffer.BlockCopy(receiveBytes,0,data,0,count);
// messageQueue.Enqueue(talkmessage);
MessageCenter.Instance.DistributeMessage(clientSocket, data);
}
}
ReceiveFromServer();
}
}//End...
MessageCenter:
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using day1_7MessageData;
namespace Day1_7EVEServer
{
public class MessageCenter
{
private static MessageCenter instance;
///// 套接字对应的客户端名字
//public Dictionary<Socket, string> socketDic = new Dictionary<Socket, string>();
/// 用户列表
public List<string> userList = new List<string>();
public bool isAddUser = false;
public TalkMessage talk;
/// 消息类型对应消息处理类
public Dictionary<ushort, IMessage> messageTypeDic = new Dictionary<ushort, IMessage>();
//接受的消息队列
public Queue<TalkMessage> messageQueue = new Queue<TalkMessage>();
public static MessageCenter Instance
{
get
{
if (instance==null) {
instance = new MessageCenter();
}
return instance;
}
}
public MessageCenter() {
Regist();
}
/// <summary>
/// 注册消息处理类
/// </summary>
public void Regist() {
OnLineState online = new OnLineState();
messageTypeDic.Add(online.GetID, online);
TalkState ts = new TalkState();
messageTypeDic.Add(ts.GetID, ts);
}
//派发消息
public void DistributeMessage(Socket clientSocket,byte[] packageMessage) {
//根据包的包头,派发消息
MessagePackage mPackage=MyTools.Instance.SplitPackage(packageMessage);
if (messageTypeDic.ContainsKey(mPackage.packageID))
{
messageTypeDic[mPackage.packageID].DisposeMessage(clientSocket, mPackage);
}
else {
Console.WriteLine("字典中不存在的消息类型");
}
}
}
}
using System.Collections.Generic;
using System.Net.Sockets;
using day1_7MessageData;
namespace Day1_7EVEServer
{
public class MessageCenter
{
private static MessageCenter instance;
///// 套接字对应的客户端名字
//public Dictionary<Socket, string> socketDic = new Dictionary<Socket, string>();
/// 用户列表
public List<string> userList = new List<string>();
public bool isAddUser = false;
public TalkMessage talk;
/// 消息类型对应消息处理类
public Dictionary<ushort, IMessage> messageTypeDic = new Dictionary<ushort, IMessage>();
//接受的消息队列
public Queue<TalkMessage> messageQueue = new Queue<TalkMessage>();
public static MessageCenter Instance
{
get
{
if (instance==null) {
instance = new MessageCenter();
}
return instance;
}
}
public MessageCenter() {
Regist();
}
/// <summary>
/// 注册消息处理类
/// </summary>
public void Regist() {
OnLineState online = new OnLineState();
messageTypeDic.Add(online.GetID, online);
TalkState ts = new TalkState();
messageTypeDic.Add(ts.GetID, ts);
}
//派发消息
public void DistributeMessage(Socket clientSocket,byte[] packageMessage) {
//根据包的包头,派发消息
MessagePackage mPackage=MyTools.Instance.SplitPackage(packageMessage);
if (messageTypeDic.ContainsKey(mPackage.packageID))
{
messageTypeDic[mPackage.packageID].DisposeMessage(clientSocket, mPackage);
}
else {
Console.WriteLine("字典中不存在的消息类型");
}
}
}
}
通用的消息接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace Day1_7EVEServer
{
public interface IMessage
{
/// <summary>
/// 返回消息的编号
/// </summary>
ushort GetID { get; }
/// <summary>
/// 处理消息
/// </summary>
void DisposeMessage(Socket clientSocket, MessagePackage mPackage);
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace Day1_7EVEServer
{
public interface IMessage
{
/// <summary>
/// 返回消息的编号
/// </summary>
ushort GetID { get; }
/// <summary>
/// 处理消息
/// </summary>
void DisposeMessage(Socket clientSocket, MessagePackage mPackage);
}
}
通用的工具类,MyTools,TalkMessage(protobuf工具生成),MessagePackage
using ProtoBuf;
using System.IO;
using System;
/// <summary>
/// 我的工具类
/// </summary>
public class MyTools : SingleTon<MyTools> {
//封包
public byte[] BuilderPackage(MessagePackage mPackage)
{
byte[] idBytes = BitConverter.GetBytes(mPackage.packageID);
byte[] protobufBytes = mPackage.protobufBytes;
byte[] lengthBytes = BitConverter.GetBytes((ushort)(4 + protobufBytes.Length));
byte[] data = new byte[idBytes.Length + protobufBytes.Length + lengthBytes.Length];
Buffer.BlockCopy(idBytes, 0, data, 0, idBytes.Length);
Buffer.BlockCopy(lengthBytes, 0, data, idBytes.Length, lengthBytes.Length);
Buffer.BlockCopy(protobufBytes, 0, data, 4, protobufBytes.Length);
return data;
}
//拆包
public MessagePackage SplitPackage(byte[] data)
{
MessagePackage mPackage = new MessagePackage();
byte[] idBytes = new byte[2];
byte[] lengthBytes = new byte[2];
byte[] protobufBytes = new byte[data.Length - 4];
Buffer.BlockCopy(data, 0, idBytes, 0, idBytes.Length);
Buffer.BlockCopy(data, 2, lengthBytes, 0, 2);
Buffer.BlockCopy(data, 4, protobufBytes, 0, protobufBytes.Length);
mPackage.packageID = BitConverter.ToUInt16(idBytes, 0);
mPackage.packageLength = BitConverter.ToUInt16(lengthBytes, 0);
mPackage.protobufBytes = protobufBytes;
return mPackage;
}
//序列化
public byte[] ProtoBufSerialized<T>(T obj)
{
byte[] data = null;
if (obj != null)
{
using (MemoryStream ms = new MemoryStream())
{
Serializer.Serialize<T>(ms, obj);
data = new byte[ms.Length];
ms.Position = 0;
ms.Read(data, 0, data.Length);
ms.Dispose();
}
}
return data;
}
//反序列化
public T ProtoBufDesSerialized<T>(byte[] data)
{
for (int i = 0; i < data.Length; i++)
{
Console.WriteLine(data[i]);
}
T obj = default(T);
if (data.Length > 0)
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(data,0,data.Length);
ms.Position = 0;
//可能会出错
obj = Serializer.Deserialize<T>(ms);
}
}
return obj;
}
}
using System.IO;
using System;
/// <summary>
/// 我的工具类
/// </summary>
public class MyTools : SingleTon<MyTools> {
//封包
public byte[] BuilderPackage(MessagePackage mPackage)
{
byte[] idBytes = BitConverter.GetBytes(mPackage.packageID);
byte[] protobufBytes = mPackage.protobufBytes;
byte[] lengthBytes = BitConverter.GetBytes((ushort)(4 + protobufBytes.Length));
byte[] data = new byte[idBytes.Length + protobufBytes.Length + lengthBytes.Length];
Buffer.BlockCopy(idBytes, 0, data, 0, idBytes.Length);
Buffer.BlockCopy(lengthBytes, 0, data, idBytes.Length, lengthBytes.Length);
Buffer.BlockCopy(protobufBytes, 0, data, 4, protobufBytes.Length);
return data;
}
//拆包
public MessagePackage SplitPackage(byte[] data)
{
MessagePackage mPackage = new MessagePackage();
byte[] idBytes = new byte[2];
byte[] lengthBytes = new byte[2];
byte[] protobufBytes = new byte[data.Length - 4];
Buffer.BlockCopy(data, 0, idBytes, 0, idBytes.Length);
Buffer.BlockCopy(data, 2, lengthBytes, 0, 2);
Buffer.BlockCopy(data, 4, protobufBytes, 0, protobufBytes.Length);
mPackage.packageID = BitConverter.ToUInt16(idBytes, 0);
mPackage.packageLength = BitConverter.ToUInt16(lengthBytes, 0);
mPackage.protobufBytes = protobufBytes;
return mPackage;
}
//序列化
public byte[] ProtoBufSerialized<T>(T obj)
{
byte[] data = null;
if (obj != null)
{
using (MemoryStream ms = new MemoryStream())
{
Serializer.Serialize<T>(ms, obj);
data = new byte[ms.Length];
ms.Position = 0;
ms.Read(data, 0, data.Length);
ms.Dispose();
}
}
return data;
}
//反序列化
public T ProtoBufDesSerialized<T>(byte[] data)
{
for (int i = 0; i < data.Length; i++)
{
Console.WriteLine(data[i]);
}
T obj = default(T);
if (data.Length > 0)
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(data,0,data.Length);
ms.Position = 0;
//可能会出错
obj = Serializer.Deserialize<T>(ms);
}
}
return obj;
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// Generated from: TalkMessage.proto
namespace day1_7MessageData
{
[global::System.Serializable, global::ProtoBuf.ProtoContract([email protected]"TalkMessage")]
public partial class TalkMessage : global::ProtoBuf.IExtensible
{
public TalkMessage() {}
private string _name = "";
[global::ProtoBuf.ProtoMember(1, IsRequired = false, [email protected]"name", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue("")]
public string name
{
get { return _name; }
set { _name = value; }
}
private string _data = "";
[global::ProtoBuf.ProtoMember(2, IsRequired = false, [email protected]"data", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue("")]
public string data
{
get { return _data; }
set { _data = value; }
}
private global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
{ return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
}
}
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// Generated from: TalkMessage.proto
namespace day1_7MessageData
{
[global::System.Serializable, global::ProtoBuf.ProtoContract([email protected]"TalkMessage")]
public partial class TalkMessage : global::ProtoBuf.IExtensible
{
public TalkMessage() {}
private string _name = "";
[global::ProtoBuf.ProtoMember(1, IsRequired = false, [email protected]"name", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue("")]
public string name
{
get { return _name; }
set { _name = value; }
}
private string _data = "";
[global::ProtoBuf.ProtoMember(2, IsRequired = false, [email protected]"data", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue("")]
public string data
{
get { return _data; }
set { _data = value; }
}
private global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
{ return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 要发送的数据包
/// </summary>
public class MessagePackage {
/// <summary>
/// 协议号
/// </summary>
public ushort packageID;
/// <summary>
/// 包的长度
/// </summary>
public ushort packageLength;
/// <summary>
/// 数据类的字节数组
/// </summary>
public byte[] protobufBytes;
}
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 要发送的数据包
/// </summary>
public class MessagePackage {
/// <summary>
/// 协议号
/// </summary>
public ushort packageID;
/// <summary>
/// 包的长度
/// </summary>
public ushort packageLength;
/// <summary>
/// 数据类的字节数组
/// </summary>
public byte[] protobufBytes;
}
具体的消息处理类,OnLineState,TalkState
using System.Net.Sockets;
using day1_7MessageData;
namespace Day1_7EVEServer
{
/// <summary>
/// 上线状态
/// </summary>
public class OnLineState : IMessage
{
public ushort GetID
{
get
{
return 1001;
}
}
public OnLineState() { }
/// <summary>
/// 收到所有的名字给客户端,接收到UserList中
/// </summary>
/// <param name="clientSocket"></param>
/// <param name="mPackage"></param>
public void DisposeMessage(Socket clientSocket, MessagePackage mPackage)
{
TalkMessage users =MyTools.Instance.ProtoBufDesSerialized<TalkMessage>(mPackage.protobufBytes);
MessageCenter.Instance.messageQueue.Enqueue(users);
PrintToConsole.Instance.PrintTo("我的名字" + users.data);
PrintToConsole.Instance.PrintTo("我的名字" + users.name);
MessageCenter.Instance.talk = users;
if (!MessageCenter.Instance.userList.Contains(users.name))
{
MessageCenter.Instance.userList.Add(users.name);
MessageCenter.Instance.isAddUser = true;
}
}
}
}
using day1_7MessageData;
using System.Net.Sockets;
namespace Day1_7EVEServer
{
public class TalkState : IMessage
{
public ushort GetID
{
get
{
return 1002;
}
}
public void DisposeMessage(Socket clientSocket, MessagePackage mPackage)
{
TalkMessage users = MyTools.Instance.ProtoBufDesSerialized<TalkMessage>(mPackage.protobufBytes);
MessageCenter.Instance.messageQueue.Enqueue(users);
}
}
}
using day1_7MessageData;
namespace Day1_7EVEServer
{
/// <summary>
/// 上线状态
/// </summary>
public class OnLineState : IMessage
{
public ushort GetID
{
get
{
return 1001;
}
}
public OnLineState() { }
/// <summary>
/// 收到所有的名字给客户端,接收到UserList中
/// </summary>
/// <param name="clientSocket"></param>
/// <param name="mPackage"></param>
public void DisposeMessage(Socket clientSocket, MessagePackage mPackage)
{
TalkMessage users =MyTools.Instance.ProtoBufDesSerialized<TalkMessage>(mPackage.protobufBytes);
MessageCenter.Instance.messageQueue.Enqueue(users);
PrintToConsole.Instance.PrintTo("我的名字" + users.data);
PrintToConsole.Instance.PrintTo("我的名字" + users.name);
MessageCenter.Instance.talk = users;
if (!MessageCenter.Instance.userList.Contains(users.name))
{
MessageCenter.Instance.userList.Add(users.name);
MessageCenter.Instance.isAddUser = true;
}
}
}
}
using day1_7MessageData;
using System.Net.Sockets;
namespace Day1_7EVEServer
{
public class TalkState : IMessage
{
public ushort GetID
{
get
{
return 1002;
}
}
public void DisposeMessage(Socket clientSocket, MessagePackage mPackage)
{
TalkMessage users = MyTools.Instance.ProtoBufDesSerialized<TalkMessage>(mPackage.protobufBytes);
MessageCenter.Instance.messageQueue.Enqueue(users);
}
}
}
服务器:
Sererver
using System;
using System.Net;
using System.Net.Sockets;
/// 服务器
namespace Day1_7EVEServer
{
public class Server
{
private static Server instance;
Socket serverSocket;
public IPEndPoint point;
public string ip="169.254.152.25";
public int port=52121;
byte[] receiveBytes = new byte[1024];
/// 单例
public static Server Instance
{
get
{
if (instance == null) {
instance = new Server();
}
return instance;
}
}
//构造函数初始化成员变量
public Server()
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
point = new IPEndPoint(IPAddress.Parse(ip), port);
}
/// 开启服务器
public void StartServer()
{
serverSocket.Bind(point);
serverSocket.Listen(20);
StartAccept();
}
/// 开启服务器接受连接
public void StartAccept() {
serverSocket.BeginAccept(AcceptCallBack,null);
}
/// 异步接受连接回调
private void AcceptCallBack(IAsyncResult ar)
{
Socket clientSocket=serverSocket.EndAccept(ar);
Console.WriteLine("有客户端连接服务器");
//开启异步接受
clientSocket.BeginReceive(receiveBytes,0,receiveBytes.Length,SocketFlags.None,ReceiveCallBack,clientSocket);
//递归调用
StartAccept();
}
/// 异步接受消息回调
private void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = null;
try
{
clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
byte[] data = new byte[count];
Buffer.BlockCopy(receiveBytes, 0, data, 0, count);
if (count > 0)
{
//收到的消息是正确的,则派发消息
MessageCenter.Instance.DistributeMessage(clientSocket,data);
//递归接受
clientSocket.BeginReceive(receiveBytes, 0, receiveBytes.Length, SocketFlags.None, ReceiveCallBack, clientSocket);
}
else
{
//收到的消息是不正确的说明,客户端已经掉线
MessageCenter.Instance.socketDic.Remove(clientSocket);
clientSocket.Close();
}
}
catch (Exception e)
{
//用户非正常的掉线
Console.WriteLine(e);
clientSocket.Close();
}
}
}
}
using System.Net;
using System.Net.Sockets;
/// 服务器
namespace Day1_7EVEServer
{
public class Server
{
private static Server instance;
Socket serverSocket;
public IPEndPoint point;
public string ip="169.254.152.25";
public int port=52121;
byte[] receiveBytes = new byte[1024];
/// 单例
public static Server Instance
{
get
{
if (instance == null) {
instance = new Server();
}
return instance;
}
}
//构造函数初始化成员变量
public Server()
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
point = new IPEndPoint(IPAddress.Parse(ip), port);
}
/// 开启服务器
public void StartServer()
{
serverSocket.Bind(point);
serverSocket.Listen(20);
StartAccept();
}
/// 开启服务器接受连接
public void StartAccept() {
serverSocket.BeginAccept(AcceptCallBack,null);
}
/// 异步接受连接回调
private void AcceptCallBack(IAsyncResult ar)
{
Socket clientSocket=serverSocket.EndAccept(ar);
Console.WriteLine("有客户端连接服务器");
//开启异步接受
clientSocket.BeginReceive(receiveBytes,0,receiveBytes.Length,SocketFlags.None,ReceiveCallBack,clientSocket);
//递归调用
StartAccept();
}
/// 异步接受消息回调
private void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = null;
try
{
clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
byte[] data = new byte[count];
Buffer.BlockCopy(receiveBytes, 0, data, 0, count);
if (count > 0)
{
//收到的消息是正确的,则派发消息
MessageCenter.Instance.DistributeMessage(clientSocket,data);
//递归接受
clientSocket.BeginReceive(receiveBytes, 0, receiveBytes.Length, SocketFlags.None, ReceiveCallBack, clientSocket);
}
else
{
//收到的消息是不正确的说明,客户端已经掉线
MessageCenter.Instance.socketDic.Remove(clientSocket);
clientSocket.Close();
}
}
catch (Exception e)
{
//用户非正常的掉线
Console.WriteLine(e);
clientSocket.Close();
}
}
}
}
主函数
using System;
namespace Day1_7EVEServer
{
class Program
{
static void Main(string[] args)
{
//开启服务器
Server.Instance.StartServer();
//暂停控制台
Console.ReadKey();
}
}
}
namespace Day1_7EVEServer
{
class Program
{
static void Main(string[] args)
{
//开启服务器
Server.Instance.StartServer();
//暂停控制台
Console.ReadKey();
}
}
}