using
System.Collections;
using
System.Collections.Generic;
using
UnityEngine;
using
System.Net.Sockets;
using
System.Net;
using
System;
using
System.Text;
//工具类
public
class
NetworkManager {
#region
单例
private
static
NetworkManager
instance;
private
NetworkManager(){}
public
static
NetworkManager
Instance{
get
{
if
(instance
==
null
)
{
instance
=
new
NetworkManager
();
}
return
instance;
}
}
#endregion
//定义一个委托,来表示一类的方法,只要是方法是这种类型
//都可以使用这种委托来实现回调
public
delegate
void
MyCallBack(
string
msg);
#region
服务器端
/*服务器创建流程
1、创建服务器
2、等待客户端连接
3、发送消息
4、接受消息
要使用到Socket中的方法有:
1、创建套接字的方法
2、绑定端口号和IP的方法
3、监听的方法
4、接收客户端连接请求的方法(Accept)
5、收发消息的方法
*/
#endregion
//服务器委托对象,主要实现向外界传输数据
MyCallBack
m_serverCallBack;
//服务器端的套接字对象
Socket
m_serverSocket;
//服务端的输入输出的缓存区
byte
[] m_serverBuffer;
//初始化服务器
public
void
ServerInit(
MyCallBack
userCallBack){
m_serverCallBack
=
userCallBack;
//实例化输入输出数组
m_serverBuffer
=
new
byte
[
1024
];
//实例化服务器Socket
m_serverSocket
=
new
Socket
(
//使用IP地址的类型
AddressFamily.InterNetwork,
//套接字类型,使用的TCP的流式传输,
//还有UDP的报文式传输:QQ的传输方式
SocketType.Stream,
//选取协议,流式传输不一定是Tcp协议
ProtocolType.Tcp
);
//IP地址的绑定和端口号版定
//IPAddress.Any:表示能够接受所有连接的IP地址类型
//第二个参数:端口号,IP表示的是哪个电脑,端口号
//表示哪个应用
IPEndPoint
point
=
new
IPEndPoint
(IPAddress.Any,
34567
);
//将节点绑定到socket上
m_serverSocket.Bind(point);
//服务器开启监听客户端连接,该方法调用成功,即
//表示服务器启动成功,10表示能够连接的最大连接
//数目,比如说玩游戏时进入需要排队,就是服务器
//设置了连接数据
m_serverSocket.Listen(
10
);
//开启的回调
m_serverCallBack(
"服务器启动成功"
);
//服务器开启等待用户连接的状态
//第一个参数:这是一个方法,如果有客户端连接当前的服务器了,
//该方法会自动调用
m_serverSocket.BeginAccept(ServerAccept,m_serverSocket);
}
//当服务器收到用户请求连接的时候的回调方法
void
ServerAccept(
IAsyncResult
ar){
//获取到当前客户端连接服务器的套接字
m_serverSocket
=
ar.AsyncState
as
Socket;
//得到新的套接字,针对当前连接的客户端
Socket
workingSocket
=
m_serverSocket.EndAccept(ar);
//给客户端发送一个连接成功的消息
workingSocket.Send(Encoding.Unicode.GetBytes(
"Hello,I accept your requedt at"
+
DateTime.Now.ToShortDateString()));
//开始基于建立新的Socket连接,进行收发消息
workingSocket.BeginReceive(
//收发缓存区
m_serverBuffer,
//接受消息的开始位置
0
,
//接受数据的长度
m_serverBuffer.Length,
//是否需要开启其他服务,None表示什么消息都接受
SocketFlags.None,
//接收到消息之后的回调
ServerReceive,
//当前套接字的状态
workingSocket
);
//尾递归
m_serverSocket.BeginAccept(ServerAccept,m_serverSocket);
}
//服务器收到消息的回调方法
void
ServerReceive(
IAsyncResult
ar){
//获取到新的套接字
Socket
workingSocket
=
ar.AsyncState
as
Socket
;
//得到接收的字节个数
int
count
=
workingSocket.EndReceive(ar);
//将接受到的内容转成字符串
string
msgResult
=
UTF8Encoding.UTF8.GetString(m_serverBuffer);
//回调
m_serverCallBack(
"接收到了"
+
count
+
"字节数据"
);
m_serverCallBack(msgResult);
//尾递归调用
workingSocket.BeginReceive(
m_serverBuffer,
0
,
m_serverBuffer.Length,
SocketFlags.None,
ServerReceive,
workingSocket
);
}
//************************************************** */
#region
客户端
//客户端套接字
Socket
m_clientSocket;
//客户端消息缓存区
byte
[] m_clientBuffer;
//客户端的回调
MyCallBack
m_clientCallBack;
//客户端连接服务器的方法
//ip:要连接的服务器地址
//port:端口号,要连接哪个应用
//userCallback:客户端各种回调
public
void
ClinetConnect(
string
ip,
int
port,
MyCallBack
userCallback){
//初始化客户端套接字
m_clientSocket
=
new
Socket
(
//IP类型
AddressFamily.InterNetwork,
//套接字类型
SocketType.Stream,
//协议类型
ProtocolType.Tcp
);
//初始化客户端缓存区
m_clientBuffer
=
new
byte
[
1024
];
//开始连接服务器
//IPAddress.Parse:解析IP
m_clientSocket.Connect(IPAddress.Parse(ip),port);
//将连接的回调传递进来
m_clientCallBack
=
userCallback;
m_clientCallBack(
"连接服务器成功!!"
);
//客户端开始准备接受服务器的回复
m_clientSocket.BeginReceive(
m_clientBuffer,
0
,
m_clientBuffer.Length,
SocketFlags.None,
//客户端接收消息的回调
ClientReceive,
m_clientSocket
);
}
//接收到服务器回应的回调方法
void
ClientReceive(
IAsyncResult
ar){
//得到新的套接字
Socket
workingSocket
=
ar.AsyncState
as
Socket
;
//接收到的数据的长度
int
count
=
workingSocket.EndReceive(ar);
//将接受到的数据转成字符串
string
msgResult
=
UTF8Encoding.UTF8.
GetString(m_clientBuffer);
//回调
m_clientCallBack(
"收到了"
+
count
+
"字节的数据"
);
m_clientCallBack(msgResult);
//重置一下buffer
m_clientBuffer
=
new
byte
[
1024
];
//开始递归接收
m_clientSocket.BeginReceive(
m_clientBuffer,
0
,
m_clientBuffer.Length,
SocketFlags.None,
ClientReceive,
workingSocket
);
}
#endregion
}