Socket长连接服务器
发布时间:2019-04-29 11:46:00 来源: 互盟云
前面我们讲过了Web服务器,本节课我们来介绍Socket服务器,实时对战类的游戏都是长连接服务器,实时的数据交互。网络游戏中,进行主客机消息收发很重要,我们之后会讲到具体的实现,现在我们来搭建一个简单的socket服务器。
socket服务器处理客户端以角色为核心,role就代表一个客户端,服务器中接受连接的是ServerSocket,每一个客户端有一个ClientSocket保存在Role中,数据交互使用每一个固定的DBModel操作数据库读取数据,role使用roleManager去管理。
启动服务器先初始化ip和端口号,创建socket绑定并开始监听,并启用新的线程。当有新的客户端连接就创建新的role并添加新rolemanager中进行管理。
privatestaticstringm_ServerIP="192.168.0.114";
privatestaticintm_Port=1038;
privatestaticSocketm_ServerSocket;
staticvoidMain(string[]args)
{
//实例化socket
m_ServerSocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//向操作系统申请一个可用的ip和端口用来通讯
m_ServerSocket.Bind(newIPEndPoint(IPAddress.Parse(m_ServerIP),m_Port));
//设置最多3000个排队连接请求
m_ServerSocket.Listen(3000);
Console.WriteLine("启动监听{0}成功",m_ServerSocket.LocalEndPoint.ToString());
ThreadmThread=newThread(ListenClientCallBack);
mThread.Start();
Console.ReadLine();
}
///监听客户端连接
privatestaticvoidListenClientCallBack()
{
while(true)
{
//接收客户端请求
Socketsocket=m_ServerSocket.Accept();
Console.WriteLine("客户端{0}已经连接",socket.RemoteEndPoint.ToString());
//Console.WriteLine("客户端{0}已经连接",((IPEndPoint)socket.RemoteEndPoint).Address.ToString());
if(((IPEndPoint)socket.RemoteEndPoint).Address.ToString()=="192.168.0.114")
{
RechargeCtrl.Instance.Recharge(socket);
}
else
{
//一个角色就相当于一个客户端
Rolerole=newRole();
ClientSocketclientSocket=newClientSocket(socket,role);
//把角色添加到角色管理
RoleMgr.Instance.AllRole.Add(role);
}
}
}
ClientSocket里面封装了与客户端通信的一些方法,包括发送请求,接受数据等等,发送数据要放在队列里面一条一条的去发送,数据要进行加解密的过程。数据过来需要进行拆包的过程,一个包体有包体的长度和包体内容两个部分组成,包体长度用来判断数据是否接受完成。这个类中的实现相对来说对刚接触的同学不太好理解,但是这一部分都是固定的,所以多看几遍就熟悉了。
///监听客户端连接
///</summary>
privatestaticvoidListenClientCallBack()
{
while(true)
{
//接收客户端请求
Socketsocket=m_ServerSocket.Accept();
Console.WriteLine("客户端{0}已经连接",socket.RemoteEndPoint.ToString());
//Console.WriteLine("客户端{0}已经连接",((IPEndPoint)socket.RemoteEndPoint).Address.ToString());
if(((IPEndPoint)socket.RemoteEndPoint).Address.ToString()=="192.168.0.114")
{
RechargeCtrl.Instance.Recharge(socket);
}
else
{
//一个角色就相当于一个客户端
Rolerole=newRole();
ClientSocketclientSocket=newClientSocket(socket,role);
//把角色添加到角色管理
RoleMgr.Instance.AllRole.Add(role);
}
}
}
RoleMgr角色管理器就是用来保存所有的角色,这样当服务器需要同步消息的时候可以回去相应的角色进行收发消息。
publicclassRoleMgr
{
privateRoleMgr()
{
m_AllRole=newList<Role>();
}
#region单利
privatestaticobjectlock_object=newobject();
privatestaticRoleMgrinstance;
publicstaticRoleMgrInstance
{
get
{
if(instance==null)
{
lock(lock_object)
{
if(instance==null)
{
instance=newRoleMgr();
}
}
}
returninstance;
}
}
#endregion
privateList<Role>m_AllRole;
publicList<Role>AllRole
{
get
{
returnm_AllRole;
}
}
publicRoleGetRole(introleId)
{
for(inti=0;i<m_AllRole.Count;i++)
{
if(m_AllRole[i].RoleId==roleId)returnm_AllRole[i];
}
returnnull;
}
}
客户端收发消息也是大同小异,只是它只负责连接一个服务器的socket,收发消息的逻辑基本上是一样的,大家可以去自己完成客户端的逻辑。
大家感兴趣可以关注此公众号,Unity游戏开发大本营,我会经常在这里分享游戏开发相关的文章。
本文来源:
https://www.humengyun.com/news-view-646.html