首页 > Windows开发 > 详细

C#服务器全面讲解与制作

时间:2019-09-18 22:09:06      阅读:115      评论:0      收藏:0      [点我收藏+]

C#服务器全面讲解与制作一

            环境配置与基础架构

  • 环境配置

  • 基础的服务器架构

 

 

这里我会讲解高级的C#服务器的全面制作流程

会对大家有很大的帮助

不过在这个教程中主要是讲解服务器的制作,所以不会讲解客户端的制作,不过会提供相关客户端的代码。

 

1 环境配置

1.1 VS code环境配置

  如果你觉得用Visual Studio来写代码是一件很酷的事情,那么可以直接略过这个部分,到下一个安装Visual Studio 2019的部分

  我们在开发之前需要先配置开发环境,由于这里使用的是.Net core来进行开发,所以先在官网下载.Net core的SDK,我这里用的是.Net core2.2的开发环境

  技术分享图片

   下载完成后双击安装就行啦,我觉得这个就不用教了吧。。。

   那么就进入下一步,到这里下载VS code,什么!VS code是哪个???看下图即可

  技术分享图片

 

   同理下载后安装即可

  接着就是对C#的支持了,虽然VS code可以支持很多种语言,但不代表下载之后就有这么高超的能力,我们还需要配置一波

  技术分享图片

 

   是不是就配置好了呢,对的呢,下来就是很厉害的一部分了,在VS code中对终端的操作需要熟悉一些才行,下来会讲解以下如何新建一个.Net core的项目,会用到很多命令哦

  不过不用太过担心,毕竟只是一些很简单的命令

  首先,我们创建一个文件夹,emm。。。是在win的文件管理器中按下CTRL + SHIFT + N创建的哪种,嗯?为什么不用命令?这个问题问的好,其实你会用终端的话不需要我告诉你你就会了的,就是mkdir <文件夹名>嘛

  既然这么想学那我就顺带提一下,如果想要召唤终端出来需要学习一个简单的召唤术,这个其实很简单,CTRL + ~就能召唤出来啦

   技术分享图片

 

   下面的哪个TERMINAL就是终端啦,如果你用了汉化包就当我什么都没说,因为汉化过来就叫终端

  下来我来解析一下(推了推眼镜)

技术分享图片

 

   红色部分就是当前文件的位置了,这里给一些简单的指令,输入进去之后点击回车(Enter)就能执行啦 

cd <DirName> //进入名字为<DirName>的文件夹 夹全名其实是change directory
cd ./     //进入当前目录。。。不要问我为什么会有这种指令,它的存在在某些时刻很有意义,这里就不详解了
cd ../     //返回上级目录

mkdir <DirName> 创建一个文件夹

  所以在这里我们先使用mkdir来新建一个文件夹,如果你是CTRL + K + O或是直接在外面新建一个文件夹文件夹拖进来就当我什么都没说

  这里我们新建一个名字叫MyServer的文件夹

  技术分享图片

 

  这样就新建成功了,下来使用cd进入我们新建的文件夹

  技术分享图片

   这样我们就可以在这个文件夹里面部署自己的项目啦

  不过怎么新建一个项目呢,这里我们可以使用dotnet new console来新建一个控制台(console)项目

  技术分享图片

 

  看看左边的文件树,可以看到出现了很多文件

  技术分享图片

 

   如果没有怎么办呢?那就去文件夹的地址把文件夹拖进来就行啦

  如果你直接输入dotnet new会列出很多项目,可以按自己的需求选择,这里就不演示了

  不过你以为这样就完了?你可以输入dotnet run来试试运行这个项目,虽然不知道为什么我这里运行成功了,如果运行不成功的话记得输入dotnet restore来修复一下项目

  技术分享图片

 

   技术分享图片

 

   这样我们的项目就创建完成啦,在左边的文件树点击一下program.cs就能在视窗看到代码了

   技术分享图片

 1.2 Visual Studio 2019环境配置

   点击这里下载Visual Studio 2019的安装包

   技术分享图片

 

  对于我们的开发其实个人版就已经足够了,打开其实是一个Installer,安装好2019版本之后启动installer

  技术分享图片

 

 

 

   点击修改进入配置

  技术分享图片

 

 

   选择.Net Core跨平台开发

  技术分享图片

 

 

   最后点击右下角的修改就行了,默默等待安装,装完就能启动啦。

  

2 服务器的基础架构

2.1 配置服务器

   首先定义一个StartServer方法来写入启动服务器的代码

namespace MyServer
{
    class Program
    {
        static void Main(string[] args)
        {
            StartServer();
        }

        static void StartServer(){
            
        }
    }
}

 

  这里暂时先这么写,到后期会慢慢向外展开,目前是初始阶段不适合一开始就弄一个类出来

  为了不让StartServer运行结束后程序结束,我们添加一个while循环,接收服务端的输入,如果输入了exit就代表服务器该结束了,我们就跳出这个循环

   不过为了服务器的运行不那么莫名其妙,所以在初始化完成后输出一个成功信息并给出一些友好的提示

        static void Main(string[] args)
        {
            StartServer();
            Console.WriteLine("服务器初始化完毕,输入exit结束服务");
            while (true) {
                string msg = Console.ReadLine(); 
                if (msg.Equals("exit")) { 
            break; } } }

 

我是如何解释这些代码的

  如果是修改过的部分会被标记出来 如 新代码

  如果是被被删除的的代码,会被划掉被标记出来 不需要的代码

  如果一个方法里代码过多 会用 ... 来代表被省略的代码

  下来就是服务器运行相关的代码了

  这里我们需要创建一个套接字(Socket),里面储存的主要是一个地址和一些传输的协议,一般情况下<Socket>.xxx(这里的<Socket>代表Socket类型的变量)代表让封装的地址做xxx或是对封装的地址做xxx,不过这些都是下来说的了,这里就简单的了解一下就行

  首先,我们要使用IPV4的网络协议,也就是常用的ip地址进行链接,例如本机的ipv4地址是127.0.0.1

  然后使用流形式的数据传输,这样主要是可以保证数据的传输顺序,不会出现后发的数据跑到前面去,不然发个”你好“别人接受到是”好你“就不对劲了,而且TCP协议用的就是Stream的数据形式,用其他不匹配的信息方式是会报错的。

  最后就是使用Tcp协议了,这里就默认大家对TCP协议已有过了解,毕竟网上对TCP的讲解一大堆,这里就不赘述了。

        static void StartServer() {
            //                                使用IPV4             使用流形式的数据传输      使用TCP协议
            Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        }

  

  下来就是定义一个绑定的IP:Port,这里我们叫做地址,区别于IP地址,下来客户端可以通过这个地址访问到我们的服务器,这里我们绑定到本地的8989端口,毕竟正常情况下不可能去绑定别人的IP地址开服务器,至少在这里不是,就用固定的127.0.0.1就行了。

  首先定义一个IPAddress来指定IP地址,然后创建一个IPEndPoint来指定我们服务器即将绑定的端口

 

        static void StartServer() {
            //                        使用IPV4                  使用流形式的数据传输      使用TCP协议
            Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Tcp);

       IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
       IPEndPoint iPEndPoint = new IPEndPoint(ipAddress, 8989);
        }

 

  下来就是绑定这个地址了,这里使用<Socket>.Bind(IP:Port)来绑定一个地址,让我们的客户端通过这个地址来访问我们的服务器

  接着使用<Socket>.Listen(<int Num>)来定义我们的服务器最多可以连接多少个客户,这里我们定义的是10,如果连接的客户达到10那么将会被拒绝其它客户的连接请求

 

        static void StartServer() {
            ...
            IPEndPoint iPEndPoint = new IPEndPoint(ipAddress, 8989);
server.Bind(iPEndPoint);
server.Listen(10);
        }    

 

  不过这样写代码未免有些太多,我们将代码简化一些,

    

        static void StartServer() {
       ...
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint iPEndPoint = new IPEndPoint(ipAddress, 8989);
            server.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8989));
            server.Listen(10);
        }

 

    这样我们的服务器配置工作就完成啦

 

2.2 接收用户

  现在服务器的初始化已经完成了

  接着就该是让我们的服务器接收用户的时候了

  简单的调用<Socket>.BeginAccept(<AsyncCallback func>,<object param>)来开启一个异步的用户接收,这里的异步接收可以理解为开了一个线程,不过异步不一定就是多线程,在用户接入的时候会调用AsyncCallback委托类型的回调函数func,如果有参数传递的需要可以传递一个参数param到回调函数中。

  这里我们先这么写,假设我们有一个不存在的方法AcceptCallBack,而且我们将创建的server传递过去

 

        static void StartServer() {
            ...
            server.Listen(10);

            server.BeginAccept(AcceptCallBack,server);
        }

 

  如果你用的是Visual Studio,那么很幸运的是,你可以点击一下这个不存在的方法的名字,使用CTRL + .来自动生成这个方法,如果是VS code的话可能需要自己写,毕竟我没怎么用过,也不是很清楚。

  这个方法需要一个IAsyncResult类型的参数,里面包含了异步请求的数据,包括我们之前传递过来的<Socket server>变量

 

        static void StartServer() {...}

        private static void AcceptCallBack(IAsyncResult ar) {
}

  

  这里我们获取一下传递过来的<Socket server>变量,实际上传递的变量都封装在了<IAsyncResult>.AsyncState里面

  

        private static void AcceptCallBack(IAsyncResult ar) {
            Socket server = ar.AsyncState as Socket;
        }

 

as是如何运作的?

as在C#中是强制转换的一个变体,如果能转换到对应的class则返回class状态的变量,否则返回null,正常写法中可以用下图表示。

 

 

技术分享图片

 

 

 

 

  用户接入后<Socket server>应当结束接收来获取接入的客户端套接字,这样我们就接受到用户啦,为了给我们一个提示,所以简单的输出用户接入即可

  结束接收的方法需要将异步信息传入才能读取出接入的用户

  

  

        private static void AcceptCallBack(IAsyncResult ar) {
            Socket server = ar.AsyncState as Socket;

            Socket client = server.EndAccept(ar);
Console.WriteLine($"用户{client.AddressFamily}接入");
        }

 

$的工作原理?

上面$"用户{client.AddressFamily}"代码可以替换为 “接收到用户信息” + client.AddressFamily

$是C#中的一个语法糖,在Java中可以用 string.Format来达到目的 如String.format("接收到用户信息:%s", msg);
在C#中是使用
string.Format("接收到用户信息:{0}",msg)
$即是一个合并字符串的简写方法

 

  下一篇会讲解服务器欢迎语的发送

  

 3 最后。。。

  现在我们服务器的基础部分就已经完成啦,下面给一个全局图方便观看

  技术分享图片

 

 

   接着就是客户端的代码了

 

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

namespace TCP客户端
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clientSocket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8899));
            Console.WriteLine("press any key to continue");
            Console.Read();
            clientSocket.Close();
        }
    }
}

 

C#服务器全面讲解与制作

原文:https://www.cnblogs.com/fentsoul/p/11544497.html

(1)
(1)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!