NewLife.Net——开始网络编程

网络编程的重要性就不说了,先上源码:https://github.com/nnhy/NewLife.Net.Tests

一个服务端,就是监听一些端口,接收客户端连接和数据,进行处理,然后响应。

/// <summary>定义服务端,用于管理所有网络会话</summary>
class MyNetServer : NetServer<MyNetSession>
{
}

/// <summary>定义会话。每一个远程连接唯一对应一个网络会话,再次重复收发信息</summary>
class MyNetSession : NetSession<MyNetServer>
{
    /// <summary>客户端连接</summary>
    public override void Start()
    {
        base.Start();

        // 欢迎语
        var str = String.Format("Welcome to visit {1}!  [{0}]\r\n", Remote, Environment.MachineName);
        Send(str);
    }

    /// <summary>收到客户端数据</summary>
    /// <param name="e"></param>
    protected override void OnReceive(ReceivedEventArgs e)
    {
        WriteLog("收到:{0}", e.Packet.ToStr());

        // 把收到的数据发回去
        Send(e.Packet);
    }
}

服务端核心类是NetServer,一般来说,每个网络服务端都会写一个自己的类来继承NetServer,以方便编写自己的NetSession会话逻辑。

实在简单的应用,也可以直接实例化NetServer,然后通过事件来处理收到的连接和数据。

这里我们写了个MyNetServer,没有任何代码,仅仅是为了指定使用哪个网络会话类。

网络会话NetSession非常重要,每一个Tcp连接就对应一个会话,对Udp来说同一个远端套接字(IP+端口)就是一个会话。

网络会话最重要的有几块:

  1. Start会话开始,Tcp三次握手之后,双方还没有发送数据包之前,此时可以做一些准备工作,或者向客户端发送欢迎语。Udp会话开始在第一个数据包达到时。
  2. OnReceive接收,每次收到数据包以后,都会触发该方法,数据包位于e.Packet。Tcp默认同步处理,未完成当前数据包处理之前,不会接收本连接的下一个数据包。
  3. Send发送。发送Packet数据包给本会话连接的客户端,扩展方法支持发送字符串或数据流。

!!!注意:粘包问题在OnReceive之前处理,下回有专门文章分析,接收数据的ReceivedEventArgs里面还有个Message,支持编码器对数据包进行解码成为消息。

本例程是Echo回声程序,因此OnReceive把收到的数据包原样发回去。

服务端用法很简单

static NetServer _server;
static void TestServer()
{
    // 实例化服务端,指定端口,同时在Tcp/Udp/IPv4/IPv6上监听
    var svr = new MyNetServer
    {
        Port = 1234,
        Log = XTrace.Log
    };
    svr.Start();

    _server = svr;
}

指定端口和日志,然后就可以开始服务了。

默认在Tcp/Udp/IPv4/IPv6上监听,客户端爱用哪个协议来连接都行。

当然,NetServer还可以支持多个端口同时监听,共用数据处理代码。

客户端用法更简单

var uri = new NetUri("tcp://127.0.0.1:1234");
var client = uri.CreateRemote();
client.Log = XTrace.Log;
client.Received += (s, e) =>
{
    XTrace.WriteLine("收到:{0}", e.Packet.ToStr());
};
client.Open();

for (var i = 0; i < 5; i++)
{
    Thread.Sleep(1000);

    var str = "你好" + (i + 1);
    client.Send(str);
}

client.Dispose();

这里的NetUri直接从字符串里面解析协议、地址、端口,然后CreateRemote建立客户端。这里会自动识别Tcp/Udp。

也是指定日志,方便我们查看工作过程。还有两个开关 LogSend/LogReceive能输出更详细的数据包日志。

Received事件里面处理收到的数据包。

Open开始连接服务端,如果网络不同,这里会抛出异常。Tcp客户端有断线重连机制。

发送数据包也很简单,直接Send就好,高级应用需要在发送后等待响应数据,可以用 await SendAsync。

因为程序很简单,也可以用telnet命令来测试该服务端。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的SOD蜜

使用“消息服务框架”(MSF)实现分布式事务的三阶段提交协议(电商创建订单的示例)

1,示例解决方案介绍 在上一篇 《消息服务框架(MSF)应用实例之分布式事务三阶段提交协议的实现》中,我们分析了分布式事务的三阶段提交协议的原理,现在我们来看看...

3279
来自专栏飞雪无情的博客

Go语言经典库使用分析(五)| Negroni 中间件(一)

上一篇介绍的Gorilla Handlers中间件,严格来说不能称之为一个库或者框架,他只是一系列包装http.Handler的中间件函数,并且他们之间没有任何...

823
来自专栏NetCore

Identity Service - 解析微软微服务架构eShopOnContainers(二)

接上一篇,众所周知一个网站的用户登录是非常重要,一站式的登录(SSO)也成了大家讨论的热点。微软在这个Demo中,把登录单独拉了出来,形成了一个Service,...

2625
来自专栏我和未来有约会

Silverlight 3.0 中的 Local Connection

现在很多的需求中需要一个插件实例和另一个实例进行通讯。在同一个页面中调用Html、js等来通讯,而这个往往有一些限制,需要专门的去设置一些权限。在Silverl...

2147
来自专栏野路子程序员

【Laravel5】Auth组件重写密码认证方式为MD5加密

1.2K6
来自专栏技术博客

Asp.Net MVC 3.0 使用Gzip压缩

Gzip最早由Jean-loup Gailly和Mark Adler创建,用于Unix系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是G...

1162
来自专栏草根专栏

使用Identity Server 4建立Authorization Server (6) - js(angular5) 客户端

由于手头目前用项目, 所以与前几篇文章不同, 这次要讲的js客户端这部分是通过我刚刚开发的真是项目的代码来讲解的. 这是后端的代码: https://githu...

5685
来自专栏草根专栏

使用Identity Server 4建立Authorization Server (1)

本文内容基本完全来自于Identity Server 4官方文档: https://identityserver4.readthedocs.io/ 官方文档很详...

49610
来自专栏Netkiller

PHP高级编程之守护进程

PHP高级编程之守护进程 http://netkiller.github.io/journal/php.daemon.html 摘要 2014-09-01 发表...

3787
来自专栏Felix的技术分享

《一个操作系统的实现》笔记(2)--保护模式

3698

扫码关注云+社区

领取腾讯云代金券