北大青鸟作业题之: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;
}
}
}
}
...全文
412 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的呗

110,533

社区成员

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

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

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