C#服务器全面讲解与制作
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, );
}
下来就是绑定这个地址了,这里使用<Socket>.Bind(IP:Port)来绑定一个地址,让我们的客户端通过这个地址来访问我们的服务器
接着使用<Socket>.Listen(<int Num>)来定义我们的服务器最多可以连接多少个客户,这里我们定义的是10,如果连接的客户达到10那么将会被拒绝其它客户的连接请求
static void StartServer() {
...
IPEndPoint iPEndPoint = new IPEndPoint(ipAddress, );
server.Bind(iPEndPoint);
server.Listen();
}
不过这样写代码未免有些太多,我们将代码简化一些,
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"), ));
server.Listen();
}
这样我们的服务器配置工作就完成啦
2.2 接收用户
现在服务器的初始化已经完成了
接着就该是让我们的服务器接收用户的时候了
简单的调用<Socket>.BeginAccept(<AsyncCallback func>,<object param>)来开启一个异步的用户接收,这里的异步接收可以理解为开了一个线程,不过异步不一定就是多线程,在用户接入的时候会调用AsyncCallback委托类型的回调函数func,如果有参数传递的需要可以传递一个参数param到回调函数中。
这里我们先这么写,假设我们有一个不存在的方法AcceptCallBack,而且我们将创建的server传递过去
static void StartServer() {
...
server.Listen(); 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); $即是一个合并字符串的简写方法 |
下一篇会讲解服务器欢迎语的发送
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"), ));
Console.WriteLine("press any key to continue");
Console.Read();
clientSocket.Close();
}
}
}
C#服务器全面讲解与制作的更多相关文章
- python 跑服务器,访问自己制作的简单页面
1 python 跑服务器,访问自己制作的简单页面 2 # win+b出现一个网址http:/0.0.1:5000/复制到浏览器查看# http://127.0.0.1:5000/home 做这个首 ...
- 联想服务器thinkserver TS550 Raid5制作及winserver2012R2 安装过来
一. 联想服务器thinkserver TS550 Raid5制作 1.开机后按ctrl+i 进入raid配置模式 2.选择“1”配置所需Raid模式(这次配的是raid5) 3.按提示确认后退出 ...
- Android九宫格图片(9.png)的讲解与制作
刚开始学习Android的时候,会见到res/drawable的几个文件里面有*.9.png格式命名的图片文件.起初以为这只是Android素材的一些特殊命名,其实不是.它是能实现图片素材拉伸.收缩不 ...
- Spring IOC和DI原理讲解并制作LazyCoder版的Spring (一)
转载请注意出处:http://blog.csdn.net/zcm101 写在前面的话 最近,给项目组成员培训了Spring 控制反转和依赖注入的原理,并自己做了个Lazy Coder版的Spring, ...
- UltraISO制作使用(服务器装机u盘制作)
1.准备工作: 1)U盘一个,需要格式化(大于4G,毕竟ISO文件就已经大于4G了) 2)CentOS7.1 iso文件一个(去这里下载:http://www.centoscn.com/) 3)Ult ...
- Windows服务器下,Tomcat制作成服务自启动,跑不起来,报内存溢出。
测试过不行 使用服务启动后,tomcat运行时会抛出各种内存溢出错误,于是我第一时间想到的是去修改catalina.bat文件中的内存设置,但是然并卵,于是我又尝试不用服务,去使用startup.ba ...
- PHP绘图案例讲解验证码制作
<?php header("Content-type: image/png");//声明浏览器解析为图片 $width=200; $height=100; $color1=i ...
- 使用asp.net从零开始制作设计网站---转载
首先感谢提供此教程的朋友,可以给大家学习的机会,很有用,留着好好学.如下正文: 1. 申请域名 2. 购买空间 3. 备案 4. 使用photoshop完成设计与切图 5. 使用dreamweave ...
- 账号控管:NIS服务器
NIS服务器 sun最开始命名为 Yellow pages ,黄页, NIS = YP; 14.1 NIS的由来与功能 NIS--Network information services( ...
随机推荐
- 图上的并行处理 Parallel Processing of Graphs
Graph 本次学术前沿讲座由邵斌老师主讲,标题已经揭示了主题:Graph.1.5h的talk,听完自觉意犹未尽.本来以为是一节自己没接触过的图形学的talk,没想到讲的很多内容都跟自己学过的很多东西 ...
- [技术博客]Pyqt5实现Widget内部拖拽
Pyqt5实现Widget内部拖拽 在本次项目的beta迭代中,程序需要在需要在QListWidget内实现对于添加后的测试序列,可以通过鼠标拖拽的方式来移动测试序列,方便用户操作. 允许拖拽 ...
- Python快速入门教程【转】
第一章 Python基础知识 1.1 介绍 1.1.1 特点 Python是一种面向对象.解释型计算机程序设计语言.语法简洁清晰,强制用空白符作为语句缩进. Python ...
- 图形化SQL JOIN
- Deepin系统中手动开启swap的方法
Deepin系统中手动开启swap的方法 如何设置 swap(交换空间)的大小建议设置和你的实际物理内存一样大,如你的内存是8G的,则可将下面的count的值设为8192(当然这只是参考值,你可根据你 ...
- t6_sumdoc
C:\Users\Administrator\Documents\sumdoc 2019\sumdoc t6 final\sumdoc t615C:\Users\Administrator\Docum ...
- sumdoc t411 dir.txt
C:\Users\zhoufeiyue\Documents\sumdoc t411\(9+条消息)redis Jedis存取list对象和map - shenjianxz的博客 - CSDN博客.mh ...
- C#实体类null自动转空字符串
C#实体类null自动转空字符串 using System.ComponentModel.DataAnnotations; [DisplayFormat(ConvertEmptyStringToNul ...
- FileHelper-文件操作工具
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io ...
- but only one is allowed(重复处理跨域请求)
情景:vue的项目中在本地调试项目,在前端的跨域配置没有问题的情况下,出现这样的报错. 解决方案,参考: https://www.cnblogs.com/zsg88/articles/11576324 ...