前言

henu考试要考的,最近也没什么安排,简单记录一下

c# ip和端口

IPv4

IPv4编址方案使用由4字节组成的二进制值进行识别,我们常见的形式是将4字节分别用十进制表示,中间用圆点分开,这种方法叫做点分十进制表示法。

A类:0.x.x.x~127.x.x.x(32位二进制最高位为0)
B类:128.x.x.x~191.x.x.x(32位二进制最高2位为10)
C类:192.x.x.x~223.x.x.x(32位二进制最高3位为110)
D类:224.x.x.x~239.x.x.x(32位二进制最高4位为1110)
E类:240.x.x.x~255.x.x.x(32位二进制最高5位为11110)

子网掩码

子网掩码是用于标识IP地址中网络部分和主机部分的分界线的一种掩码,它通常与IP地址一起使用,用于将IP地址分成不同的子网,是判断任意两台计算机的IP地址是否属于同一子网的依据,以便于在局域网或广域网中进行路由选择。

IP地址与子网掩码的关系可以简单地理解为:两台计算机各自的IP地址与子网掩码进行二进制“与”运算后,如果得出的结果是相同的

网段

网段通常由IP地址和子网掩码共同定义。比如,192.168.0.0/24表示的是以192.168.0.0为网络地址,子网掩码为255.255.255.0的一个网段,其中前24位是网络地址,后8位是主机地址。在这个网段中,最多可以容纳256台主机。

编程实现

域名解析

  1. IPAddress实例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    using System.Net
    IPAddress ip = IPAddress.Parse("192.168.1.2");//Parse方法将IP地址字符串转换为IPAddress的实例

    string ipAddressString = "192.168.1.";
    string str1 = "1";
    IPAddress ipAddress;
    if (IPAddress.TryParse(ipAddressString+str1, out ipAddress))
    {
    // 转换成功,可以使用ipAddress实例了
    // ...
    }
    else
    {
    // 转换失败,处理错误情况
    // ...
    }
  2. DNS 解析
    Dns.GetHostEntry()方法用于查询指定主机名或IP地址的DNS信息,并返回一个IPHostEntry类型的对象,该对象包含了该主机的多个IP地址、别名和其他相关信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     	
    //GetHostEntry(String)
    // 查询 www.example.com 的 DNS 信息,
    IPHostEntry host = Dns.GetHostEntry("www.example.com");

    // 查询 192.168.0.1 的 DNS 信息
    IPHostEntry host = Dns.GetHostEntry("192.168.0.1");


    //GetHostEntry(IPAddress)
    IPHostEntry host = Dns.GetHostEntry(ip);//IPHostEntry类的实例中包含了Internet主机的相关信息,常用属性有AddressList属性和HostName属性。
    try
    {
    hostname = host.HostName.ToString();
    }
    catch (Exception)
    {
    hostname = "不能获取";
    }

数据流

编码

字符串不同编码之间的转换

1
2
3
4
5
string s = "abcd";
Encoding unicode = Encoding.Unicode;
Encoding utf8 = Encoding.UTF8;
byte[] b = Encoding.Convert(unicode, utf8, unicode.GetBytes(s));
string s1 = utf8.GetString(b);

字符串与字节码的转换

1
2
3
4
Encoding en = Encoding.GetEncoding("GB2312");
byte[] bytes = en.GetBytes("abcd123");//按照GB2312的规则转换为字节编码
textBlock2.Text = en.GetString(bytes);//字节码编码

FileStream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//文件在/bin/debug 目录下(在右侧项目直接添加没用)
FileStream fs = new FileStream("1.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
//或者FileStream imageFile = File.OpenRead(filePath);

byte[] buffer = new byte[1024];//设置缓冲区
//目标文件流
FileStream fsNew = new FileStream("2.txt", FileMode.Create, FileAccess.ReadWrite);
//读取
while (fs.Read(buffer, 0, buffer.Length) > 0)
{
//解码(文件流读取的是字节序列)
Console.WriteLine(Encoding.UTF8.GetString(buffer));
//写入目标文件流
fsNew.Write(buffer, 0, buffer.Length);
}
fs.Close();
fsNew.Close();

Stream Reader Writer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//stream reader writer 只适用于文本(txt),实际是一个封装的简化文本传输的类            
FileStream fs = new FileStream("1.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
FileStream fsNew = new FileStream("2.txt", FileMode.Create, FileAccess.ReadWrite);
StreamReader sr = new StreamReader(fs,Encoding.Unicode);//默认是UTF8

StreamWriter sw = new StreamWriter(fsNew);
//StreamWriter sw = File.CreateText ("C:\\file1.txt");

string strLine;
while ((strLine=sr.ReadLine())!=null)//在判断条件里面已经调用了一次readline (每次都会少一行)
{
sw.WriteLine(strLine);
}
fs.Close();
sr.Close();
sw.Close();
//如果先执行 fsNew.Close( );再执行 sw.Close( );将引发异常。因为在StreamWriter的Close函数调用过程中,将调用Flush函数,而此时fs已经被关闭,Flush将产生异常。

binary reader writer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  FileStream fs = new FileStream("3.txt", FileMode.CreateNew, FileAccess.ReadWrite);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(0);//int为4个字节
float ft = 1;
bw.Write(ft);
bw.Write("the wcf is easy");
fs.Position = 0;
//bw.close()执行,fs流就会关闭,fs 就是不可读的状态了
//对该流未处理完不要关
StreamReader sr = new StreamReader(fs);
BinaryReader br = new BinaryReader(fs);
int x1 = br.ReadInt32();
float x2 = br.ReadSingle();
string s = br.ReadString();//读取一整个string
//注意顺序
Console.WriteLine("{0}, {1}, {2}", x1, x2, s);
br.Close();
fs.Close();

数据的加密和解密

对称加密

常见的对称加密算法有DES,SHA-1,AES
利用AES算法实现文件加密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/// <summary>使用AES算法加密</summary>
public static byte[] Encryptstring(string strpath,byte[] key,byte[] iv)
{
byte[] encrpted;
using (Aes aesAlg = Aes.Create())
{
//创建加密器
ICryptoTransform encryptor = aesAlg.CreateEncryptor(key, iv);
//创建文件流
FileStream fs = new FileStream(strpath, FileMode.Open, FileAccess.ReadWrite);
CryptoStream cs = new CryptoStream(fs, encryptor, CryptoStreamMode.Read);//读取文件流并创建加密流
using (BinaryReader br = new BinaryReader(cs))//using代码块执行完毕后,文件流将会被自动释放
{
encrpted = br.ReadBytes(10240);//使用BinaryReader一次行读取字节
}
fs.Close();
cs.Close();
}
return encrpted;
}

/// <summary>使用AES算法解密</summary>
ICryptoTransform decryptor = aesAlg.CreateDecryptor(key, iv);
FileStream fs = new FileStream(strpath, FileMode.Open, FileAccess.ReadWrite);
CryptoStream cs = new CryptoStream(fs,decryptor,CryptoStreamMode.Read);

/// <summary>根据提供的密码生成Key和IV</summary>
public static void GenKeyIV(string password, out byte[] key, out byte[] iv)
{
using (Aes aesAlg = Aes.Create())
{
key = new byte[aesAlg.Key.Length];
byte[] pwdBytes = Encoding.UTF8.GetBytes(password);
for (int i = 0; i < pwdBytes.Length; i++)
{
key[i] = pwdBytes[i];
}
iv = new byte[aesAlg.IV.Length];
for (int i = 0; i < pwdBytes.Length; i++)
{
iv[i] = pwdBytes[i];
}
}
}

不对称加密算法

常用的不对称加密算法,RSA算法,ECC算法

动态绘图

InkCanvas(墨迹画板)

1
using System.Windows.Controls

属性设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public MyInkCanvas() 
{ //DefaultDrawingAttributes属性用于获取或设置InkCanvas中新笔画的绘制特性
DrawingAttributes inkDa = new DrawingAttributes
{
Color = Colors.Red,
Height = 10,
Width = 10,
StylusTip = StylusTip.Rectangle//Rectangle(矩形)
};//该属性的可选值有:Color(笔画颜色)、Width(触笔宽度)、Height(触笔高度)、StylusTip(触笔形状,圆形或者矩形)
this.DefaultDrawingAttributes = inkDa;
this.EditingMode = InkCanvasEditingMode.Ink;
//EditingMode属性指定了触笔、手指、鼠标等设备与InkCanvas交互的模式,属性的值用InkCanvasEditingMode枚举来表示,默认值为Ink
//可选的枚举值有:Ink(接收墨迹)、GestureOnly(只响应笔势或手势但不接收墨迹)、None(不执行任何操作)
}

常用事件

  1. StylusDown事件:用户在InkCanvas控件上用触笔、手指与图面接触,或者按鼠标左键时,都会引发StylusDown事件
  2. StylusMove事件:用户在InkCanvas控件内移动触笔或手指,或者按住鼠标左键移动鼠标时,都会引发StylusMove事件
  3. StylusUp事件:用户释放鼠标左键、拿开触笔或者抬起手指时,都会引发StylusUp事件

    元素

    Strokes>Stroke>StylusPointCollection>point

    静态呈现和动态呈现

    动态呈现

    动态呈现是指根据用户输入或操作实时生成和更新可视化元素和图形对象,从而不断改变呈现效果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    //动态绘制
    InkImage myDynamic3 = new InkImage();
    myinkcanvas.setDyanmic(myDynamic3);//绑定
    class InkImage : DynamicRenderer//实现类
    {
    public Point firstPoint;
    public BitmapImage bi;//书上没有就不多介绍了
    protected override void OnStylusDown(RawStylusInput rawStylusInput)
    {
    base.OnStylusDown(rawStylusInput);
    firstPoint = (Point)rawStylusInput.GetStylusPoints().First();//获取用户笔尖的坐标
    bi = new BitmapImage();
    bi.BeginInit();
    bi.UriSource = new Uri("images/image1.png", UriKind.Relative);
    bi.EndInit();
    }
    protected override void OnStylusMove(RawStylusInput rawStylusInput)
    {
    base.OnStylusMove(rawStylusInput);
    StylusPointCollection stylusPoints = rawStylusInput.GetStylusPoints();
    this.Reset(Stylus.CurrentStylusDevice, stylusPoints);//Reset 方法会清除之前生成的可视化呈现,并重新绘制笔画的当前状态,若没图片拉缩小时,会不断的与之前的图像重叠
    }

    protected override void OnDraw(DrawingContext drawingContext, StylusPointCollection stylusPoints, Geometry geometry, Brush fillBrush)//在用户完成笔画的绘制并松开笔尖之后触发的
    {
    Point lastPoint = (Point)stylusPoints.Last();
    Vector v = Point.Subtract(lastPoint, firstPoint);
    Rect rect = new Rect(firstPoint, v);
    drawingContext.DrawImage(bi, rect);
    }
    }

    静态呈现

    静态呈现指的是将所有可视化元素和图形对象预先生成并直接显示在屏幕上,不需要根据用户交互来进行动态更新。

静态呈现墨迹的办法是自定义从Stroke类继承的类。由于Stroke对象会自动收集StylusPoint数据、创建笔画以及将笔画添加到自定义的墨迹控件上,因此我们只需要在自定义的类中重写引发触笔事件的DrawCore方法,即可实现静态呈现功能。静态绘制是在当用户绘制完一条笔画时,通过更改数据来达到效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//OnStrokeCollected 是一个重载方法,它是 InkCanvas 控件中的一个事件处理函数。当用户在 InkCanvas上绘制完一条笔画时,会触发 OnStrokeCollected 方法
protected override void OnStrokeCollected(InkCanvasStrokeCollectedEventArgs e)
{
this.Strokes.Remove(e.Stroke);//删除用户刚刚绘制的笔画
//构造静态呈现对象
DrawImageStroke stroke3 = new DrawImageStroke(e.Stroke.StylusPoints);
this.Strokes.Add(stroke3);
}
class DrawImageStroke : Stroke
{ //图像构建
public BitmapImage bi;//BitmapImage 对象用于显示一张位图图像()
public DrawImageStroke(StylusPointCollection stylusPoints)
: base(stylusPoints)
{
bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri("images/image1.png", UriKind.Relative);
bi.EndInit();
}


//DrawCore 方法则是用于绘制笔画的核心方法,它决定InkCanvas笔画如何呈现出来
protected override void DrawCore(DrawingContext drawingContext, DrawingAttributes drawingAttributes)
{
Point firstPoint = (Point)this.StylusPoints.First();
Point lastPoint = (Point)this.StylusPoints.Last();
Vector v = Point.Subtract(lastPoint, firstPoint);//构建图像
Rect rect = new Rect(firstPoint, v);//构建矩形
drawingContext.DrawImage(bi, rect);//DrawingContext 的 DrawImage 方法来将图片绘制到该矩形区域中
}
}