C#之路

First Post:

Last Update:

Word Count:
1.5k

Read Time:
7 min

Linux下C# 开发环境搭建

doc: https://docs.microsoft.com/zh-cn/dotnet/csharp/

doc: https://www.runoob.com/csharp/csharp-tutorial.html

ref: https://wiki.archlinux.org/index.php/Mono

arch

1
2
sudo pacman -S mono
yay -S monodevelop-bin # ide

测试

a.cs

1
2
3
4
5
6
using System;
class MainClass {
public static void Main(string[] args) {
Console.WriteLine("Hello C#");
}
}

编译运行

1
2
mcs a.cs
mono a.exe

socket

socket_server.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System.Net.Sockets;
using System.Net;
using System;
using System.Text;


namespace TestSocket{
class Program {
static void Main(String[] args) {
Socket tcpServer = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipaddress = new IPAddress(new byte[]{127,0,0,1});
EndPoint point = new IPEndPoint(ipaddress, 8080);
tcpServer.Bind(point);
tcpServer.Listen(100); // 参数为最大连接数
Socket clientSocket = tcpServer.Accept(); // 阻塞接收客户端

string msg = "hello";
byte[] data = Encoding.UTF8.GetBytes(msg);
clientSocket.Send(data);
}
}
}

socket_client.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace SocketClient {
class Program {
static void Main(string[] args) {
Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//建立连接
IPAddress ipaddress = IPAddress.Parse("127.0.0.1");
EndPoint point = new IPEndPoint(ipaddress, 8080);
tcpClient.Connect(point);
byte[] data = new byte[1024];
int length = tcpClient.Receive(data);
string msg = Encoding.UTF8.GetString(data, 0, length); //转换字符串
Console.WriteLine(msg);
}
}
}

处理json

ref: https://www.cnblogs.com/cfas/p/11080203.html

将一个int转换成一个byte array,又如何将一个byte array转换成一个int

至少可以通过三种方法来进行转换。在.NET Framework类库的System名字空间中有个叫做BitConverter的类,它是专门用来进行这种转换的。它有一个GetBytes方法,对于大多数简单的类型来说,该方法都被重载了,它可以返回一个byte array来保存你传递的值。它也有几个ToTypeName方法用来将一个byte array转换成一个基本类型(primitive type):byte[] b = BitConverter.GetBytes( 0xba5eba11 ); //{0x11,0xba,0x5e,0xba} uint u = BitConverter.ToUInt32( new byte[] {0xfe, 0x5a, 0x11, 0xfa},0 ); // 0xfa115afe
在运用BitConverter类时,要记住的一个重点是它的行为取决于硬件架构(代码在该硬件架构上运行)的字节顺序(endianness)——就是 说,integer字节在内存中的存储顺序。如果你将bit保存为可以在许多不同平台上读取的一个文件格式,那么就会出问题。BitConverter有 一个公有的IsLittleEndian字段,你可以查看它是如何运行的,但遗憾的是,你并不能改变它。

也可以不用BitConverter类,而通过手动位移(bit shifting)来进行转换: b = new byte[] {0xfe,0x5a,0x11,0xfa}; u = (uint)(b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24); b[0] = (**byte**)(u); b[1] = (**byte**)(u >> 8); b[2] = (byte)(u >> 16); b[3] = (byte)(u >> 24); 用这种方法就可以避免字节顺序问题,因为可以完全控制字节的位置。

最后——如果不介意用不安全的代码——可以通过直接的内存拷贝来实现转换,把一个指向byte array的指针(pointer)转换成一个指向integer类型的指针,然后取它的值(dereference):unsafe { fixed ( byte* pb = b ) u = ((uint)pb); }

同BitConverter一样,这个方法的运行结果取决于代码在何种硬件上运行。

如果要进行很多这种转换——比如说在一个循环中——而且想得到最佳性能,那么建议用最后两种方法中的一种。BitConverter有些慢,尽管区别不大。

ref: https://www.cnblogs.com/zwq194/archive/2013/01/14/2859377.html

网络字节序问题

主机到网络:short/int/long IPAddress.HostToNetworkOrder(short/int/long)

网络到主机:short/int/long IPAddress.NetworkToHostOrder(short/int/long)

思路:

1
2
3
4
5
6
7
int x            m = IPAddress.HostToNetworkOrder(x)   BitConverter.GetBytes(m)
littel-host big bytes
0x1234 0x3421 '0x12' '0x34'


big-host big bytes
0x1234 0x1234 '0x12' '0x34'

ref: https://www.cnblogs.com/zjoch/p/6271144.html

byte[] 相加

1
2
3
4
5
6
7
8
9
//把b接在a的后面
byte[]
a = new byte[] { 1, 2, 3 },
b = new byte[] { 4, 5, 6 };
//.net3.5以上的linq方法
a = a.Concat(b).ToArray();
//.net3.0 2.0的方法
Array.Resize(ref a, a.Length+b.Length);
b.CopyTo(a, a.Length - b.Length);

ref: https://zhidao.baidu.com/question/465208303.html

打印byte[]

1
2
3
4
5
byte[] headerBytes = new byte[] {0x50, 0x53, 0x50, 0x00};
foreach (byte b in headerBytes)
{
Debug.Log(b.ToString("X2") + " ");
}

tcp Recvive函数

ref: https://zhidao.baidu.com/question/1540225953291276387.html

socket.Receive(buffer , int offset, int size, socketFlag)

socket.Receive(recvBytes,recvBytes.Length,0);

server.Receive(bytes);

数字与字符串之间的转换

ref: https://blog.csdn.net/kingscoming/article/details/78847208

byte[]操作

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
45
46
47
48
49
50
51
//休夸此地分天下
//c# byte数组各种操作
//1、网络字节序转换
float m = 5f;
var btValue = BitConverter.GetBytes(m).Reverse().ToArray();


//2、byte数组合并

byte[] data = new byte[10];
byte[] counts =new byte[3];
byte[] ndata = new byte[data.Length + counts.Length];
data.CopyTo(ndata, 0);
counts.CopyTo(ndata, data.Length);

//3、string和byte[]转换
stringbyte[]:
byte[] byteArray = System.Text.Encoding.Default.GetBytes ( str );

byte[]转string
string str = System.Text.Encoding.Default.GetString ( byteArray );

string转ASCII byte[]:
byte[] byteArray = System.Text.Encoding.ASCII.GetBytes ( str );

ASCII byte[]转string:
string str = System.Text.Encoding.ASCII.GetString ( byteArray );
//4、字符串分割成数组

string[] b = a.Split('|');

//5、int转换成16进制字节

int a = 58;
byte b = Convert.ToByte(a);
//6、byte[]截取

byte[] test = buffer.Skip(24).Take(16).ToArray();//从第24位开始截取长度16

//7、定义一个list 添加后 转换成byte[]

List<byte> frameBytes = new List<byte>();
frameBytes.Add(0x9E);
byte[] phoneNumByte=new byte[]{0x01,0x03,0x05,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00};//定义一个数组
for (int i = 0; i < phoneNumByte.Length; i++)
{
frameBytes.Add(phoneNumByte[i]);
}
frameBytes = frameBytes.Concat(dataBody).ToList<byte>();//两个list合并
byte[] transByte = frameBytes.ToArray();//list转byte[]
// List<byte> b=transByte.ToList();//byte[]转list

空值传播运算符

若event不为null,则invoke,这是C#6的新语法。 ?.称为空值传播运算符

1
2
3
4
5
6
7
8
9
//C# 5
var handler = Event;
if (handler != null)
{
handler(source, e);
}
//C# 6
var handler = Event;
handler?.Invoke(source, e);

委托的Invoke

c# – Action(arg)和Action.Invoke(arg)之间的区别?

All delegate types have a compiler-generated Invoke method.

所有的委托类型,编译器都会自动生成一个 invoke 方法.

C# allows you to call the delegate itself as a shortcut to calling this method.

用委托类型直接加参数是Invoke(参数)的一个捷径.
其实等价调用 Invoke();

类似:

1
2
3
Action<string> x = Console.WriteLine;
x("2");
x.Invoke("2");
打赏点小钱
支付宝 | Alipay
微信 | WeChat