测试是在本机测试,客户端服务器都在一个机器上,IP就用127.0.0.1
服务端
> 处理TCP通讯以及监听功能
class Server
{
Dictionary<string, Player> dics=new Dictionary<string,Player>();//所有客户端信息
static void Main(string[] args)
{
new Server().Start() ;//实例化一个对象并调用方法
}
//创建套接字 Socket所有功能
public void Start()
{
IPAddress ip = IPAddress.Parse("127.0.0.1");//给IP赋值
IPEndPoint point = new IPEndPoint(ip,500);// 端点 Ip地址和端口号
// 创建Socket IP类型 (IPV4地址) Socket类型 字节流 协议类型 TCP协议
Socket mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//服务器端的Socket才会做绑定和监听的工作
mySocket.Bind(point);// 绑定 (端点和Socket绑定,Socket中加入IP地址和端口号) 只有在服务器端用 表明是服务器端的套接字
mySocket.Listen(20);//监听是否有连接请求 20 队列 很多人同时发
while (true)//服务器端Socket核心
{//时刻监听是否有客户端连接
//等待状态 等待客户端连接 执行了这一句 等client有数据后 客户端连接进来才会向下执行
Socket client= mySocket.Accept();//阻断函数 接收客户端的Socket 等待一个Socket调用Connect方法
Console.WriteLine("由客户端连接进来");
//主线程卡住,继续监听是否有其他客户端连接进来
//客户端连接进来后数据交互的方法:分出两条分线程 分别处理两个客户端与服务端之间的数据交互
//client.Send();//发送信息给另一方 发送的时候用的byte数组
//client.Receive();//接收对方发送的消息 也是阻断方法 接收的时候也要用byte数组
//连接进来后开辟一条分线程
SocketThread st = new SocketThread(client,dics);
new Thread(new ThreadStart(st.Run)).Start();//没有添加对象直接实例化并调用方法
}
}
}
> 服务端开辟新线程处理连接进来的客户端,进行数据交互
//SocketThread线程类 每连接进来一个客户端就开一个线程
namespace SocketServer
{
class SocketThread
{
//每一个玩家的基本信息 ’‘’‘’‘’可以封装到Player中,打点调用就可以
public const int LOGIN = 1001;//请求类型
public const int TALK = 1002;
Player player;//读一无二的
Socket socket;
string name;
//也记录一份 所有玩家数据
Dictionary<string, Player> dics;
//构造函数
public SocketThread(Socket clientSocket, Dictionary<string, Player> dics)
{
this.socket = clientSocket;//得到自己的Socket
this.dics = dics;//当前有多少玩家在线
}
//分线程进行的地方
public void Run()//deleget 回调函数
{//Socket交互,是时刻进行的,服务器和客户端必须有一方断开才能断开
//添加死循环并有阻断函数
while (true)
{
//接收数据的时候在字节流中接收
//命令类型
Byte[] bytes = new Byte[4];
socket.Receive(bytes);//阻断方法 服务器Socket接收到bytes数组中
int cmd = TypeConvert.getInt(bytes, true);//字节转int true,false倒序和正序
//也可通过字符串类型进行判定
//判断命令类型
switch (cmd)
{
case LOGIN:
//封装成方法
//信息长度 字符串长度
Byte[] str_lenth = new Byte[4];