介绍和背景

TCP编程是网络编程领域最有趣的部分之一。在Ubuntu环境中,我喜欢使用.NET Core进行TCP编程,并使用本机Ubuntu脚本与TCP服务器进行通信。以前,我在.NET框架本身写了一篇关于TCP服务器和客户端的文章。现在,.NET框架本身将是开源的。我想写一些关于他们之间的沟通渠道。基本上,我只是测试在新的.NET环境下工作的情况,而不是在旧的.NET框架环境中工作。

然而,在这篇文章中,我有一大堆的额外功能可供你使用。我将向您展示您将使用的方法来构建自己的TCP服务器,使用.NET核心程序集以及如何通过网络与他们进行通信。对于客户端应用程序,我不会构建任何东西。相反,我将使用允许通过TCP和UDP协议进行通信的本地脚本。

议程是这样的:

  1. 构建和托管一个内置.NET Core的TCP服务器

  2. 启动请求并使用TCP客户端本机脚本将文本数据和文件数据发送到服务器。

这些是我会在这篇文章中引导你的一些东西,我也会澄清一切的目的。

我们不打算在这里建立任何特殊的应用程序,但是TCP是传输层中使用最广泛的协议(与UDP相反),我们经常使用的大多数应用程序和服务都依赖于这个协议。HTTP,FTP,SMTP和所有其他类似协议直接依赖于TCP,并使用基于TCP协议的套接字(端口)进行通信。因此,您可以从最小的程序中启动您的服务器,并在其上构建一个庞大的企业应用程序。它可以根据应用编程框架和连接到它的客户端(或用户)的需要进行扩展。

但是,我不打算谈论如何构建这些复杂的应用程序,但是我将简要介绍一下TCP服务器和基于客户端的通信。为什么写这个帖子?我将介绍跨平台环境下的TCP消耗。我将使用.NET Core创建服务器。其余部分将在本地完成,我将在Ubuntu中使用“nc”命令与我刚刚创建的服务器进行通信。因此,这个想法是让你了解如何在.NET Core中构建一个服务器来提高效率和控制能力,以及如何使用多个平台及其服务与服务器进行通信,从而使用户能够与TCP服务器通信。那么,让我们开始吧。

构建服务器端

在.NET环境中,System.Net命名空间包含了可用于学习和编程目的的所有参考资料。在服务器端编程任务中,我将使用TcpListener对象来处理传入的TCP通信。基本上,这是一个本地的TCP部分,你会很快习惯它。我一直在使用这个对象以及在其生命周期中使用这个对象的程序,用于我自己的个人应用程序和一些基于网络的应用程序,客户端应用程序,设备和机器能够通过路由器(调制解调器,或WLAN热点等)。这样,我可以创建一个使用TCP协议进行通信的中央服务器,并且可以使用TCP进行通信的客户端也可以从此服务器发送或接收数据。然而,我不会深入到以多种格式通过网络提交和传输数据。为了简单起见,我将把事情简单明了,因此我将不得不以纯文本格式工作。

服务器 - 客户端通信如何在TCP环境中工作的基本演示在以下创建的位图图形艺术中得到了演示:

图1:服务器 - 客户端设置

如图所示,服务器控制资源的使用和使用方式。客户端可以使用任何可以通过网络使用TCP协议进行通信的设备。服务器处理请求并授予对资源的访问权限。就像与其他程序交互一样,TCP客户端可以与TCP服务器交互,发送命令,发送请求,发送选项选择(例如选择要触发的服务)等等。然后,TCP服务器处理这些请求,并根据这些请求以及正在传递的数据的值生成响应。TCP服务器可以:

  1. 通过TCP协议处理传入的请求。

  2. 作为服务在后台运行; 哪些其他服务器也可以做。

  3. 将线路上的数据资源作为字节流发送。

  • 尽管TCP服务器被认为是共享消息的纯文本框架,但实际上不是消息,而是发送的字节。

  • TCP通信中的序列实际上是发送的字节,而不是消息。所以,客户端应该能够处理传入的字节。

  1. 提供可靠的,有序的和错误检查的方法和机制,在网络上进行通信,而不是我们正在创建的服务器,而是协议。

在.NET Core中,TCP侦听器允许您通过使用固定大小的静态缓冲区来处理可用的字节数。有时,可能不会发送数据来填充缓冲区,有时缓冲区可能不足以覆盖所有的缓冲区。

运行服务器的源代码就像下面这样简单:

  1. 实例化对象。

  2. 设置IP地址来监听和端口监听。

  3. 等待客户连接。

这一步承载服务器。在这个阶段,承载服务器的程序应该保持活动并运行,否则程序将终止,关闭服务器本身。看看下面给出的代码:

  1. IPAddress address = IPAddress.Parse(“127.0.0.1” );

  2. listener = new TcpListener(address,port);

  3. listener.Start();

  4. //代码停止服务器并使用

  5. // listener.AcceptTcpClientAsync();

  6. //获取连接客户端的函数

这段代码完成了我们在服务器端需要做的工作。即主持它。我用下面的代码实际上表示服务器正在运行,并在此刻处于活动状态。服务器本身不显示为正在运行。

  1. Console.WriteLine($ “Server started。Listen to TCP clients at 127.0.0.1:{port}” );

在这个阶段之后,我们需要停止服务器自行终止。而不是保持相同的功能,并在这行代码后,我创建了一个分离的功能,并在那里添加代码等待客户端。我们班有两个功能,

  1. 启动服务器

  2. 听客户

这是执行程序中大部分工作的第二个功能。这里是我们可以添加异步模式和多线程来支持多个客户端同时连接的地方。不过,我并不打算在这一节中进一步深入。所以,正确的代码来实际启动服务器,并听取客户端如下所示:

  1. using System;

  2. using System.Net;

  3. using System.Text;

  4. using System.Net.Sockets;

  5. namespace ConsoleApplication

  6. {

  7. class TcpHelper

  8. {

  9. privatestatic TcpListener listener { get; set; }

  10. privatestaticbool accept { get; set; } = false;

  11. publicstaticvoid StartServer(int port) {

  12. IPAddress address = IPAddress.Parse("127.0.0.1");

  13. listener = new TcpListener(address, port);

  14. listener.Start();

  15. accept = true;

  16. Console.WriteLine($"Server started. Listening to TCP clients at 127.0.0.1:{port}");

  17. }

  18. publicstaticvoid Listen()

  19. {

  20. if(listener != null && accept)

  21. {

  22. // Continue listening.

  23. while (true)

  24. {

  25. Console.WriteLine("Waiting for client...");

  26. var clientTask = listener.AcceptTcpClientAsync(); // Get the client

  27. if(clientTask.Result != null)

  28. {

  29. Console.WriteLine("Client connected. Waiting for data.");

  30. var client = clientTask.Result;

  31. string message = "";

  32. while (message != null && !message.StartsWith("quit"))

  33. {

  34. byte[] data = Encoding.ASCII.GetBytes("Send next data: [enter 'quit' to terminate] ");

  35. client.GetStream().Write(data, 0, data.Length);

  36. byte[] buffer = newbyte[1024];

  37. client.GetStream().Read(buffer, 0, buffer.Length);

  38. message = Encoding.ASCII.GetString(buffer);

  39. Console.WriteLine(message);

  40. }

  41. Console.WriteLine("Closing connection.");

  42. client.GetStream().Dispose();

  43. }

  44. }

  45. }

  46. }

  47. }

  48. }

此代码启动服务器并继续等待新的客户端。一旦客户端连接,它会向客户端请求数据,并将该数据发布到客户端发送“退出”到服务器。基本上,这是一个非常简单但功能强大的服务器示例,用于教育目的。当然,我们现在也需要从主函数中调用这些函数,以便运行该项目。

  1. public static void Main(string [] args)

  2. {

  3. //启动服务器

  4. TcpHelper.StartServer(5678);

  5. TcpHelper.Listen(); //开始聆听

  6. }

目前我们已经完成了服务器端的脚本。服务器设置好后,会听取客户端的请求和数据,它们会传递到我们的服务器上。我们现在需要运行程序并启动服务器来监听请求。我不深入.NET核心执行过程和构建过程的深入; 至于那个,看我的另一个帖子:

  • 在Linux上使用.NET Core快速启动

运行程序,只需要执行下面的命令,

运行dotnet

输出结果

如图2所示:服务器启动

正如你所看到的,TCP服务器在IP上启动,我们指定了我们在函数调用中传递的端口。

其余的留给客户端

正如我之前谈到的,我将使用本地TCP客户端而不是.NET核心的TCPClient对象,这样即使在系统上没有安装.NET的情况下也可以使用服务器(例如,使用.NET框架的TCPClient对象)。在这篇文章中,我将在Unix(Linux和衍生)系统中使用“netcat”命令脚本。沟通可以简单地完成。您可以从在线资源中了解更多关于这个脚本的内容,因为我不想再深究。我只是想演示这个用法。要了解更多信息,您可以访问以下任一网址并了解更多信息:

  1. nc - Unix,Linux命令

  2. 如何使用Netcat在VPS上建立和测试TCP和UDP连接

  3. nc(1) - Linux手册页

您将能够理解如何使用此命令来充当客户端。这也允许你创建一个充当服务器的程序脚本,监听网络上的请求,但我们对这些因素不感兴趣。相反,我们只是期待发送一个请求到服务器,并传递一些将显示在屏幕上的数据。

连接和发送数据到服务器:

第一步是连接到TCP服务器。我们需要两件事来建立连接,

  1. IP地址

  2. 端口连接

我们将把它们作为参数传递给

$ nc 127.0.0.1 5678

下面的屏幕出现(我们的服务器接受请求并返回一条消息)

图3:客户端连接

(查看我们服务器的代码,了解更多信息。 )

接下来,我们可以从这个终端发送数据,因为它需要更多的数据。我们将发送几个字节的数据,然后发送“退出”来终止连接。让我们看看这是如何工作的上下文。

图4:客户端将数据发送到服务器

我们发送了三条消息到服务器。所有这些都被检查,最后在最后一条消息,流被关闭,终端开始要求更多的命令(而不是要求更多的数据)。为什么?如果你注意,你会看到“quit”命令已经被设置为连接的终结符。当我们发送这个命令时,连接终止,我们需要再次启动连接。现在,我们来看另一边。

图5:服务器端消息日志

看看每个事件的行为如何变化。一旦我们的客户端连接,在这里记录一条消息:“客户端连接。等待数据“。当客户端连接时显示此消息。您还可以记录该客户的时间和其他详细信息。我们通过数据传递,在“退出”之后,你可以看到有一个“关闭连接”的日志,在另一端也应该显示,但不幸的是,我错过了这一点。您必须已经知道使用客户端连接到服务器并发送数据。

兴趣点

最后,这篇文章简要介绍了.NET Core中的TCP编程,以及如何通过使用其他平台服务与服务器进行通信来抽象出整个概念。

使用.net core在Ubuntu构建一个TCP服务器的更多相关文章

  1. 27、通过visual s'tudio 验证 SOCKET编程:搭建一个TCP服务器

    本文就是在windows下进行socket编程,搭建一个TCP客户端. 在visual studio下编程,首先在windows下进行初始化(这点在linux下是不需要的): /* 初始化 Winso ...

  2. Linux上构建一个RADIUS服务器详解

    作为一名网络管理员,您需要为您所需管理的每个网络设备存放用于管理的用户信息.但是网络设备通常只支持有限的用户管理功能.学习如何使用Linux上的一个外部RADIUS服务器来验证用户,具体来说是通过一个 ...

  3. 利用Swoole编写一个TCP服务器,顺带测试下Swoole的4层生命周期

    1首先我们写一个入口脚本,这里简单点的功能就是开启服务和关闭服务 <?php //CLI命令 if(isset($argv[1]) && in_array($argv[1], [ ...

  4. 用java语言构建一个网络服务器,实现客户端和服务器之间通信,实现客户端拥有独立线程,互不干扰

    服务器: 1.与客户端的交流手段多是I/O流的方式 2.对接的方式是Socket套接字,套接字通过IP地址和端口号来建立连接 3.(曾经十分影响理解的点)服务器发出的输出流的所有信息都会成为客户端的输 ...

  5. 探索使用 Golang 和 Webassembly 构建一个多人游戏服务器

    什么是 WebAssembly?由 Google.Microsoft.Mozilla.Apple 等发起的 WebAssembly 是一种新的字节码格式,主流浏览器都已经支持 WebAssembly. ...

  6. 使用promise构建一个向服务器异步数据请求

    function getJSON(Url){ return new Promise((resolve,reject)=>{ request= new XMLHttpRequest(); requ ...

  7. Node.js实战14:一个简单的TCP服务器。

    本文,将会展示如何用Nodejs内置的net模块开发一个TCP服务器,同时模拟一个客户端,并实现客户端和服务端交互. net模块是nodejs内置的基础网络模块,通过使用net,可以创建一个简单的tc ...

  8. TCP服务器程序

    Linux下编写TCP服务器调用的函数顺序为:socket -> bind -> listen -> accept -> recv/send socket 参见:http:// ...

  9. Mina、Netty、Twisted一起学(一):实现简单的TCP服务器

    MINA.Netty.Twisted为什么放在一起学习?首先,不妨先分别看一下它们官方网站对其的介绍: MINA: Apache MINA is a network application frame ...

随机推荐

  1. C-多个行内块布局

    1 消除间隔

  2. JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)

    函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用. 函数节流的原理挺简单的,估计大家都想到了,那就是定时器.当我 ...

  3. C# 使用NPOI 导出Excel

    NPOI可以在没有安装Office的情况下对Word或Excel文档进行读写操作 下面介绍下NPOI操作Excel的方法 首先我们需要下载NPOI的程序集 下载地址 http://npoi.codep ...

  4. 【JAVA零基础入门系列】Day8 Java的控制流程

    什么是控制流程?简单来说就是控制程序运行逻辑的,因为程序一般而言不会直接一步运行到底,而是需要加上一些判断,一些循环等等.举个栗子,就好比你准备出门买个苹果,把这个过程当成程序的话,可能需要先判断一下 ...

  5. SVN版本控制图标经常延时显示或未显示问题解决方法

    项目中,使用svn经常遇到,文件或文件夹图标延时显示或未显示的问题,终于找到办法解决 客户端:TortoiseSVN

  6. Spring ——依赖注入配置一些知识点

    依赖注入 依赖注入的原理与实现 依赖注入(DI)和依赖查找(Dependency Lookup)共同组成 控制反转(IoC).从原理的角度来说,依赖注入和控制反转是没 有不同的,可以看作是从两个角度来 ...

  7. 【学习】js学习笔记---数组对象

    一.属性 length 数组的大小.数组的length属性总是比数组中定义的最后一个元素的下标大一,设置属性length的值可以改变数组的大小.如果设置的值比它的当前值小,数组将被截断,其尾部的元素将 ...

  8. 浅谈oracle树状结构层级查询之start with ....connect by prior、level及order by

    浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...

  9. Spring装配Bean之XML装配bean

    在Spring刚出现的时候,XML是描述配置的主要方式,在Spring的名义下,我们创建了无数行XML代码.在一定程度上,Spring成为了XML的同义词. 现在随着强大的自动化配置和Java代码的配 ...

  10. vim下单行长文本的时候卡顿解决办法

    在vim编辑文件时,若单行过长,可能会导致vim卡顿,严重影响使用体验 估计是syntax匹配效率过滥导致.. 偶尔发现了一个临时的解决办法就是关掉syntax然后再打开,即在命令模式下 :synta ...