|
|
下面我将服务器写成了一个类,只要调用服务器端类的start方法就可启动服务器
其中Client类用来保存连上的客户端的socket和相关信息
下面代码注释比较少,如果有什么疑问可以跟贴问
Public Class GameServer
Private m_listen As Sockets.Socket
Private m_IP As Net.IPAddress
Private m_active As Boolean
Private m_Port As Int16
Private m_version As String
Private ConfigDoc As XmlDocument
Private m_started As Boolean
Private m_Clients As ArrayList
Private m_mainth As Threading.Thread
Public Property Port() As Int16
Get
Return m_Port
End Get
Set(ByVal Value As Int16)
m_Port = Value
End Set
End Property
Public Property Started() As Boolean
Get
Return m_started
End Get
Set(ByVal Value As Boolean)
m_started = Value
End Set
End Property
Public ReadOnly Property Version() As String
Get
Return m_version
End Get
End Property
Public Property isActive() As Boolean
Get
Return m_active
End Get
Set(ByVal Value As Boolean)
m_active = Value
End Set
End Property
Public Sub New()
'm_version = "Alpha " & System.Diagnostics.FileVersionInfo.GetVersionInfo("Mywow.gameserver.dll").FileVersion
'######################################################################
'检查配置文件,存在则读取,不存在则写入默认配置
ConfigDoc = New XmlDocument
m_Clients = New ArrayList
If IO.File.Exists("gameserver.conf") = True Then
ConfigDoc.Load(New IO.StreamReader("gameserver.conf", System.Text.Encoding.UTF8))
If ConfigDoc("GameServerConfig") Is Nothing Then
SetDefaultConfig() '写入默认配置
Dim st As IO.StreamWriter
st = New IO.StreamWriter("Gameserver.conf", True, System.Text.Encoding.UTF8)
ConfigDoc.Save(st)
End If
Else
SetDefaultConfig()
Dim st As IO.StreamWriter
st = New IO.StreamWriter("Gameserver.conf", True, System.Text.Encoding.UTF8)
ConfigDoc.Save(st)
End If
ReadConfig() '读取配置
'######################################################################
End Sub
Private Sub ReadConfig()
Me.m_IP = IPAddress.Parse(ConfigDoc("GameServerConfig")("ServerIP").InnerText)
Me.m_Port = Int16.Parse(ConfigDoc("GameServerConfig")("ServerPort").InnerText)
End Sub
Private Sub SetDefaultConfig()
Dim child As XmlElement, child2 As XmlElement, child3 As XmlElement
Dim root As XmlElement = ConfigDoc.CreateElement("GameServerConfig")
child = ConfigDoc.CreateElement("ServerIP")
child.InnerText = "127.0.0.001"
root.AppendChild(child)
child = ConfigDoc.CreateElement("ServerPort")
child.InnerText = "8085"
root.AppendChild(child)
ConfigDoc.AppendChild(root)
End Sub
Public Function Start() As Boolean
m_listen = New Sockets.Socket(Sockets.AddressFamily.InterNetwork, Sockets.SocketType.Stream, Sockets.ProtocolType.Tcp)
Try
m_listen.Bind(New IPEndPoint(m_IP, Port))
m_listen.Listen(5)
m_listen.Blocking = False
Catch ex As Exception
ConMsg("启动游戏服务器出错:" & ex.Message & ex.StackTrace)
Return False
End Try
m_mainth = New Threading.Thread(AddressOf MainTh)
m_mainth.Start()
ConMsg("启动游戏服务器成功,监听IP:" & m_IP.ToString & " Port:" & Port)
Started = True
Return True
End Function
Public Sub MainTh()
Dim helper As New helper.Helper, br As New BinReader '一些自写辅助类
While True
Try
Dim client As New client
client.CSocket = m_listen.Accept
While Not client.CSocket Is Nothing '检查是否用户连接,连接则执行一些初始化,并加入用户池
Dim ip As IPEndPoint = client.CSocket.RemoteEndPoint
OnAccept(client)
Dim aa As New client '自定义类,保存客户端信息
aa = m_Clients.Item(0)
Dim bb() As Byte
aa.IPAddress = ip.Address.ToString
client.IPAddress = ip.Address.ToString
client.CSocket = m_listen.Accept
End While
Catch ex As Exception
End Try
'Dim i As Integer
'For i = 0 To m_Clients.Count - 1
contin:
For Each i As client In m_Clients
If i.CSocket.Connected = False Then
m_Clients.Remove(i)
GoTo contin
End If
Dim pck() As Byte = ReadNextPack(i) '读取封包数据
While Not pck Is Nothing
Dim opcode As Int16, size As Integer, data() As Byte
opcode = Convert.ToInt16(br.ReadData(pck, BinReader.Types.UInt16, 2))
size = Convert.ToInt32(br.ReadData(pck, BinReader.Types.UInt16, 0))
ReDim data(size - 1)
data = br.ReadBytes(pck, 6, size)
ConMsg("收到" & Packet.Opcode.GetOpcodeName(opcode) & "命令")
m_pckHandler.ProcessPacket(i, opcode, data)
'pck = ReadNextPack(m_Clients.Item(i))
pck = Nothing
End While
Next i
m_SendMgr.SendAll()
m_mainth.Sleep(5)
End While
End Sub
Public Function ReadNextPack(ByVal sock As Client) As Byte()
Dim tmp() As Byte
'这里写入读取一个封包的处理过程,用Socket.Available取得当前可读取总共的字节数
'Socket.Receive接受数据,Socket.Send发送数据
Return tmp
End Function
Public Function [Stop]() As Boolean
Try
ConMsg("停止游戏服务器……")
m_mainth.Abort()
For Each i As Client In m_Clients
If i.CSocket.Connected = True Then i.CSocket.Close()
Next i
m_listen.Close()
Me.Started = False
ConMsg("已经成功关闭游戏服务器")
Catch ex As Exception
ConMsg("无法停止服务器:" & ex.Message & ex.StackTrace)
End Try
End Function
Private Sub OnAccept(ByVal client As Client)
ConMsg("登陆请求")
Dim bw As New BinWriter
m_Clients.Add(client)
End Sub
Private Sub ConMsg(ByVal msg As String)
Console.WriteLine("信息:游戏服务器:" & msg)
'Console.Write("登陆服务器===>")
End Sub
End Class
Public Class Client
Private m_CSocket As Sockets.Socket
Private m_IPAddress As String
Private m_Username As String
Public Sub New()
End Sub
Public Property CSocket() As Sockets.Socket
Get
Return m_CSocket
End Get
Set(ByVal Value As Sockets.Socket)
m_CSocket = Value
End Set
End Property
Public Property IPAddress() As String
Get
Return m_IPAddress
End Get
Set(ByVal Value As String)
m_IPAddress = Value
End Set
End Property
Public Property Username() As String
Get
Return m_Username
End Get
Set(ByVal Value As String)
m_Username = Value
End Set
End Property
End Class
|
|