北大青鸟作业题之:UDPServer

SocketUp 2012-06-14 11:47:26
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SocketUp
{
/// <summary>
/// 通知上层有数据到达委托
/// </summary>
/// <param name="stateObject"></param>
public delegate void DataArrivalHandler(StateObject stateObject);

/// <summary>
/// UDP服务器
/// </summary>
public class UDPServer
{
/// <summary>
/// 要监听的端口号
/// </summary>
private Int32 _Port;

/// <summary>
/// 缓存队列最大数量
/// </summary>
private readonly Int32 _QueueMaxCount = 1024;

/// <summary>
/// 缓存队列
/// </summary>
private Queue<IAsyncResult> _StateObjectQueue;

/// <summary>
/// 通知上层有数据到达事件
/// </summary>
public event DataArrivalHandler OnDataArrival;

/// <summary>
/// Socket
/// </summary>
private Socket _Socket;

/// <summary>
/// 是否开启服务
/// </summary>
private Boolean _Active;

/// <summary>
/// 创建一个UDPServer
/// </summary>
/// <param name="port">要监听的端口号</param>
public UDPServer(Int32 port)
{
// 初始化缓存队列
_StateObjectQueue = new Queue<IAsyncResult>(_QueueMaxCount);

// 端口号
_Port = port;
}

/// <summary>
/// 通知上层有数据到达事件
/// </summary>
/// <param name="stateObject"></param>
private void DataArrival(StateObject stateObject)
{
if (OnDataArrival != null)
{
OnDataArrival(stateObject);
}
}

/// <summary>
/// 启动
/// </summary>
public void Start()
{
if (!_Active)
{
_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, _Port);
_Socket.Bind(ipEndPoint);

StateObject stateObject = new StateObject();
stateObject.WorkSocket = _Socket;

EndPoint remoteIP = new IPEndPoint(IPAddress.Any, 0);

// 开始接收
_Socket.BeginReceiveFrom(stateObject.Buffer, 0, stateObject.Buffer.Length, SocketFlags.None, ref remoteIP, ProcessReceive, stateObject);

// 多线程处理数据
for (Int32 i = 0; i < System.Environment.ProcessorCount; i++)
{
Thread thread = new Thread(new ThreadStart(ProcessDataThread));
thread.IsBackground = true;
thread.Start();
}

// 服务启动
_Active = true;
}
}

/// <summary>
/// 接收数据,先扔缓存区
/// </summary>
/// <param name="ar"></param>
private void ProcessReceive(IAsyncResult ar)
{
lock (_StateObjectQueue)
{
if (_StateObjectQueue.Count < _QueueMaxCount)
{
_StateObjectQueue.Enqueue(ar);
}
}
}

/// <summary>
/// 处理数据,并且通知上层
/// </summary>
private void ProcessDataThread()
{
while (_Active)
{
IAsyncResult asyncResult = null;

lock (_StateObjectQueue)
{
if (_StateObjectQueue.Count > 0)
{
asyncResult = _StateObjectQueue.Dequeue();
}
}

System.Threading.Thread.Sleep(1);

if (asyncResult != null)
{
StateObject stateObject = asyncResult.AsyncState as StateObject;
EndPoint remoteIP = new IPEndPoint(IPAddress.Any, 0);
Int32 receiveLength = stateObject.WorkSocket.EndReceiveFrom(asyncResult, ref remoteIP);
stateObject.RemoteIP = remoteIP;
stateObject.ReceiveLength = receiveLength;

// 触发事件通知上层
DataArrival(stateObject);

// 继续接收
stateObject.WorkSocket.BeginReceiveFrom(stateObject.Buffer, 0, stateObject.Buffer.Length, SocketFlags.None, ref remoteIP, ProcessReceive, stateObject);
}
}
}

/// <summary>
/// 停止服务
/// </summary>
public void Stop()
{
if (_Active)
{
_Active = false;

if (_Socket != null)
{
_Socket.Close();
_Socket = null;
}
}
}
}
}



using System;
using System.Net;
using System.Net.Sockets;

namespace SocketUp
{
/// <summary>
/// 传输对象
/// </summary>
public class StateObject
{
public Socket WorkSocket = null;
public Int32 ReceiveLength = 0;
// 5K
public Byte[] Buffer = new Byte[5120];
public EndPoint RemoteIP = null;
}
}



using System;
using System.Windows.Forms;
using SocketUp;

namespace Server
{
public partial class FormMain : Form
{
UDPServer _UDPServer;

public FormMain()
{
InitializeComponent();
}

private void DataArrival(StateObject stateObject)
{
// 分析协议
}

private void btnStart_Click(object sender, EventArgs e)
{
if (_UDPServer == null)
{
_UDPServer = new UDPServer(1024);
_UDPServer.OnDataArrival += DataArrival;
_UDPServer.Start();
}
}

private void btnStop_Click(object sender, EventArgs e)
{
if (_UDPServer != null)
{
_UDPServer.Stop();
_UDPServer = null;
}
}
}
}
...全文
587 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
代码小天王 2012-06-20
  • 打赏
  • 举报
回复
楼主你想多了 C#更多的是封装 不管你是用SocketAsyncEventArgs还是BeginInvok在底层调用的API都是一样的
[Quote=引用 2 楼 的回复:]

不要这样打击初学者喂
虽然现在有SocketAsyncEventArgs,但多学一个BeginXXXXX也不是坏事
[/Quote]
threenewbee 2012-06-15
  • 打赏
  • 举报
回复
作为一个培训机构,就算它面对的是水平比较低或者期望不高的求学者,也不能用糊弄的过时的程序打发学员。
threenewbee 2012-06-15
  • 打赏
  • 举报
回复
初学者应该学新的东西,因为新的东西不见得比旧的高深,而且更加有用。

如果你不是特别有钱并且闲着没事而跑去学骑马,我说你不如去学开车,并非打击你。也没有说开车就比骑马高级的意思。
SocketUp 2012-06-15
  • 打赏
  • 举报
回复
不要这样打击初学者喂
虽然现在有SocketAsyncEventArgs,但多学一个BeginXXXXX也不是坏事
threenewbee 2012-06-15
  • 打赏
  • 举报
回复
北大青鸟的程序还停留在C# 1.0时代。

也许听上去没什么。但是想象一下,一个现在的人还在用Pentium 4 1.7G的电脑,用着Windows 98或者Me,连接着56kbps的猫,上的网站没有淘宝,没有腾讯,没有开心网,csdn还叫程序员大本营。还在使用bp机,不使用手机上网……这是怎样的场景。
嘶吼的蚂蚁 2012-06-15
  • 打赏
  • 举报
回复
对,北大青鸟确实够出名了!o(∩_∩)o 哈哈....
SocketUp 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

lz没说意图,难道是广告帖?
[/Quote]

没做广告啊,北大青鸟已经够出名了,不需要我做广告了
发在这里只是当作学习过程中的记录而已

天下如山 2012-06-15
  • 打赏
  • 举报
回复
表示有压力 自己自学出生的程序员。
只在此山中 2012-06-15
  • 打赏
  • 举报
回复
lz没说意图,难道是广告帖?
铜臂阿铁木 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

作为一个培训机构,就算它面对的是水平比较低或者期望不高的求学者,也不能用糊弄的过时的程序打发学员。
[/Quote]

曹版的意思应该是他们教学没用到新的特性吧。而且满屏幕的Flag。
虽然这样的程序确实挺久远的,但是对于学员来说,有好有坏,坏处是新的不知道,好处是,这个程序在多种语言下几乎通用,因为没涉及到太多某个语言的特性,这对学员转其他语言比较有利。

不过作为一个培训机构,说直白了,应该培训出的不应该是这样的吧……应该是能干活儿的,效率高的。

没准这也和他们的培训机制有联系,他们都是C#和Java混学……
风吹腚腚凉 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
北大青鸟的程序还停留在C# 1.0时代。

也许听上去没什么。但是想象一下,一个现在的人还在用Pentium 4 1.7G的电脑,用着Windows 98或者Me,连接着56kbps的猫,上的网站没有淘宝,没有腾讯,没有开心网,csdn还叫程序员大本营。还在使用bp机,不使用手机上网……这是怎样的场景。
[/Quote]
发一下你写的4.5的呗
内容概要:本文详细介绍了MySQL中InnoDB存储引擎的逻辑存储结构及其表分区技术。InnoDB的逻辑存储单元由高到低依次为表空间、段、区、页和行,其中表空间包括系统表空间、独立表空间、通用表空间、Undo表空间和临时表空间,每种表空间具有不同的用途和管理方式。文章进一步讲解了表分区的概念与类型,包括RANGE、LIST、HASH、KEY以及多字段COLUMNS分区,阐述了分区的优势如提升查询性能、便于数据维护、支持跨物理设备存储等,并列举了实际SQL操作示例,帮助理解分区表的创建、修改、删除及重组等操作。同时指出了分区的限制条件,如最大分区数量、主键约束要求等。; 适合人群:具备一定MySQL数据库基础,从事数据库开发、运维或架构设计的技术人员,尤其是工作中涉及大数据量表管理与性能优化的1-3年经验研发人员。; 使用场景及目标:①深入理解InnoDB存储机制,优化数据库物理结构设计;②掌握表分区技术,应用于海量数据存储与高效查询场景,如日志系统、订单系统的时间分区设计;③通过分区实现数据归档、快速删除历史数据、提升查询性能等运维目标; 阅读建议:学习时应结合MySQL实际环境动手实践文中提供的SQL命令,重点关注表空间管理和分区策略的选择,理解其对性能和维护的影响,并注意分区使用中的限制条件以避免设计失误。
内容概要:本文系统介绍了GitHub Copilot的实战使用技巧,涵盖其核心功能、提示工程、上下文管理、自定义配置及常见误区。文章强调Copilot不仅是代码补全工具,更是覆盖软件开发全生命周期的AI编程助手,重点讲解如何通过上下文工程、提示词结构化、斜杠命令与聊天参与者等方式提升代码生成质量,并结合实战案例展示在测试生成、代码重构、调试、文档编写等场景中的高效应用。同时指出Copilot的局限性,倡导“人为主导、AI辅助”的协作模式,强调代码审查与安全合规的重要性。; 适合人群:具备一定编程经验,希望提升开发效率的个人开发者、团队工程师及技术管理者,尤其是正在使用或计划引入AI编程工具的研发人员。; 使用场景及目标:①掌握Copilot在测试生成、代码解释、重构优化、调试排错等方面的高级用法;②学会构建高质量提示词与自定义指令,使AI输出更贴合项目规范;③规避常见使用陷阱,实现安全、可控、高效的AI辅助开发。; 阅读建议:此文档兼具理论指导与实操示范,建议结合实际开发环境边学边练,重点关注提示工程、上下文管理与自定义指令配置,持续迭代优化使用方式,并在团队中建立统一的AI编码规范与审查机制。

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧