首页 > 编程语言 >C#服务器网络框架

C#服务器网络框架

时间:2023-04-13 14:45:48浏览次数:35  
标签:cli 框架 C# my Length new 服务器 byte data

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using Google.Protobuf;

namespace ZG5_Server
{
class NetManager: Singleton<NetManager>
{
Socket server;
public List<Client> clients = new List<Client>();
public void Init()
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ip = new IPEndPoint(IPAddress.Any, 12345);
server.Bind(ip);
server.Listen(20);
Console.WriteLine("服务器开启");
server.BeginAccept(OnAccept, null);
}

private void OnAccept(IAsyncResult ar)
{
Socket client = server.EndAccept(ar);
IPEndPoint iP = client.RemoteEndPoint as IPEndPoint;
Client cli = new Client();
cli.socket = client;
cli.name = iP.Address + ":" + iP.Port;
clients.Add(cli);
Console.WriteLine(DateTime.Now.ToString()+ " " + iP.Port + "链接");
cli.socket.BeginReceive(cli.data, 0, cli.data.Length, SocketFlags.None, OnReceive, cli);
server.BeginAccept(OnAccept, null);
}

private void OnReceive(IAsyncResult ar)
{
try
{
Client cli = ar.AsyncState as Client;
int len = cli.socket.EndReceive(ar);
if (len <= 0)
{
cli.socket.Shutdown(SocketShutdown.Both);
cli.socket.Close();
clients.Remove(cli);
Console.WriteLine(DateTime.Now.ToString() + " " + cli.name + "下线");
Leave s2c = new Leave();
s2c.PlayerId = cli.player.Id;
foreach (var item in clients)
{
if (item.player != null)
{
Send(MsgID.S2C_LEAVE, s2c.ToByteArray(), item);
}
}
}
else if (cli.socket.Connected)
{
byte[] data = new byte[len];
Buffer.BlockCopy(cli.data, 0, data, 0, data.Length);
//创建一个临时流
byte[] liu = new byte[cli.stream.Length + data.Length];
Buffer.BlockCopy(cli.stream, 0, liu, 0, cli.stream.Length);
Buffer.BlockCopy(data, 0, liu, cli.stream.Length, data.Length);
//把流替换为临时流
cli.stream = liu;
//流长度大于等于2说明流内有数据
while (cli.stream.Length >= 2)
{
//获取一个包的长度
ushort onelen = BitConverter.ToUInt16(cli.stream, 0);
//如果流的长度大于等于包的长度+2说明有一个完整包
if (cli.stream.Length >= 2 + onelen)
{
//获取一个完整包
byte[] onedata = new byte[onelen];
Buffer.BlockCopy(cli.stream, 2, onedata, 0, onedata.Length);
//获取包的消息号
int id = BitConverter.ToInt32(onedata, 0);
//获取包的消息体
byte[] body = new byte[onedata.Length - 4];
Buffer.BlockCopy(onedata, 4, body, 0, body.Length);
//消息分发
Console.WriteLine("收到消息:id" + id);
MessageCenter.Ins.Send(id, body, cli);
//剩余长度
int sylen = cli.stream.Length - (2 + onelen);
//剩余长度大于0说明还有包
if (sylen > 0)
{
byte[] sydata = new byte[sylen];
Buffer.BlockCopy(cli.stream, 2 + onelen, sydata, 0, sylen);
cli.stream = sydata;
}
else
{
cli.stream = new byte[0];
}
}
else
{
break;
}
}
#region MyRegion
//byte[] data = new byte[len];
//Buffer.BlockCopy(cli.data, 0, data, 0, len);
////将收到的消息写入流
//cli.my.Write(data, 0, data.Length);
////流长度大于等于2说明有内容(2是包长度ushort的长度)
//while (cli.my.Length >= 2)
//{
// //读取的起始点
// cli.my.Position = 0;
// int oneLen = cli.my.ReadUshort();
// //判断是否有完整包
// if (cli.my.Length >= 2 + oneLen)
// {
// //获取一个包
// byte[] oneData = new byte[oneLen];
// cli.my.Read(oneData, 0, oneData.Length);
// //解析并分发
// int id = BitConverter.ToInt32(oneData, 0);
// byte[] body = new byte[oneLen - 4];
// Buffer.BlockCopy(oneData, 4, body, 0, body.Length);
// MessageCenter.Ins().Broadcast(id, body, cli);

// int syLen = (int)cli.my.Length - (2 + oneLen);
// //判断流内是否还有剩余内容
// if (syLen > 0)
// {
// //复制出剩余内容
// byte[] syDate = new byte[syLen];
// cli.my.Read(syDate, 0, syDate.Length);
// //清空流
// cli.my.SetLength(0);
// cli.my.Position = 0;
// //将剩余内容写入流
// cli.my.Write(syDate, 0, syDate.Length);
// }
// else
// {
// //清空流
// cli.my.SetLength(0);
// cli.my.Position = 0;
// }
// }
// else
// {
// cli.my.Position = cli.my.Length;
// break;
// }
#endregion
cli.socket.BeginReceive(cli.data, 0, cli.data.Length, SocketFlags.None, OnReceive, cli);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public void Send(int id, byte[] body, Client cli)
{
byte[] head = BitConverter.GetBytes(id);
byte[] data = new byte[head.Length + body.Length];
Buffer.BlockCopy(head, 0, data, 0, head.Length);
Buffer.BlockCopy(body, 0, data, head.Length, body.Length);
//手动拼接长度
byte[] mylen = BitConverter.GetBytes((ushort)data.Length);
byte[] myData = new byte[mylen.Length + data.Length];
Buffer.BlockCopy(mylen, 0, myData, 0, mylen.Length);
Buffer.BlockCopy(data, 0, myData, mylen.Length, data.Length);
cli.socket.BeginSend(myData, 0, myData.Length, SocketFlags.None, OnSend, cli);
}

private void OnSend(IAsyncResult ar)
{
Client cli = ar.AsyncState as Client;
int len = cli.socket.EndSend(ar);
//Console.WriteLine(len);
}
}
}

 

标签:cli,框架,C#,my,Length,new,服务器,byte,data
From: https://www.cnblogs.com/Chenchen11111/p/17314757.html

相关文章

  • CAD绘图次序快捷键是什么?怎么用?
    在CAD绘图过程中,当图纸中某一图形被其他图形遮挡时,如果想要将其显示出来可以通过调整其绘图次序来实现。那么,你知道CAD绘图次序快捷键是什么吗?今天小编来给大家简单介绍一下浩辰CAD软件中CAD绘图次序快捷键是什么以及使用技巧,一起来看看吧!CAD绘图次序快捷键是什么?CAD绘图次序命......
  • 微信小程序云开发中的command简介
    微信小程序云开发(WeChatMiniProgramCloudDevelopment)是微信官方推出的一种简化小程序开发的方案。它提供了一个完整的后端云服务,支持数据库、存储、云函数等功能。在云开发中,Command是一个重要的概念,主要用于操作数据库。Command是数据库命令的构造器,它用于构造复杂的数据......
  • [HMV] Condor
    0x00配置攻击机IP:172.16.1.25靶机IP:172.16.1.1630x01攻击使用Nmap扫描目标靶机开放的端口┌──(root?Kali-VM)-[~]└─#nmap-sC-sV-p-172.16.1.163StartingNmap7.93(https://nmap.org)Nmapscanreportfor172.16.1.163Hostisup(0.00049slate......
  • 【转】检查Linux系统下是否安装了gcc、pcre、zlib、openssl环境
    1.查看gcc环境gcc-v如果Linux系统没有安装gcc编译器,会提示“Commandnotfound”。如果系统上安装了gcc编译器,这条命令就会显示出当前安装的gcc编译器是哪个版本。下图展示为已安装的信息。 2. 查看pcre环境rpm-qapcre看到pcre的版本,说明已安装,否则未安装。......
  • RocketMQ是是如何管理消费进度的?又是如何保证消息成功消费的?
    RocketMQ消费者保障消息确认机制consumer的每个实例是靠队列分配来决定如何消费消息的。那么消费进度具体是如何管理的,又是如何保证消息成功消费的?(RocketMQ有保证消息肯定消费成功的特性,失败则重试)什么是ACK消息确认机制在实际使用RocketMQ的时候我们并不能保证每次发......
  • elasticsearch认证
    【转载https://www.cnblogs.com/gavinYang/p/11199699.html】elasticsearchshield(5.0以下版本权限认证)elasticsearch5.0以下的版本要用到权限控制的话需要使用shield。下载地址:https://www.elastic.co/downloads/shield5.0以上的版本则可以使用X-Pack,shield现在只是x-pac......
  • Elasticsearch之映射
    1.1 地理坐标点数据类型1.1.1地理坐标点地理坐标点是指地球表面可以用经纬度描述的一个点。地理坐标点可以用来计算两个坐标间的距离,还可以判断一个坐标是否在一个区域中。地理坐标点需要显式声明对应字段类型为geo_point:1.1.2经纬度坐标格式如上例,location字段被声......
  • bpmn.icon
    https://cdn.staticaly.com/gh/bpmn-io/bpmn-font/master/dist/demo.html......
  • 如何利用Socks5代理防止爬虫被封禁
      在当前互联网环境下,爬虫已经成为了许多企业和个人获取信息的重要途径。然而,很多网站都设置了反爬虫机制,导致许多爬虫被封禁或者被限制访问。在这种情况下,利用Socks5代理是一个不错的解决方案。  Socks5代理是一种网络协议,它能够将网络请求通过代理服务器进行转发。Socks5......
  • 用chartGPT自动生成的贪吃蛇游戏
    importpygameimporttimeimportrandom#初始化Pygame库pygame.init()#定义游戏窗口大小WINDOW_WIDTH=500WINDOW_HEIGHT=500#定义游戏速度SPEED=15#创建游戏窗口screen=pygame.display.set_mode((WINDOW_WIDTH,WINDOW_HEIGHT))#设置游戏标题py......