Unity網絡開發快速回顧

知識點來源:總結人間自有韜哥在, 唐老獅,豆包

目錄

  • 1.網絡通信-通信必備知識-IP地址和端口類
  • 2.網絡通信中序列化和反序列化2進制數據
  • 3.Socket類
  • 4.TCP同步服務端和客戶端基礎實現
    • 4.1.服務端基本實現
    • 4.2.客戶端實現:
  • 5.區分消息類型
  • 6.分包和粘包
  • 7.TCP同步退出消息和心跳消息
    • 7.1.客服端主動斷開連接
    • 7.2.心跳消息
  • 8.Socket類TCP異步常用成員
  • 9.UDP
  • 10.Socket類UDP異步常用方法
  • 11.FTP
    • 11.1.FTP上傳文件
    • 11.2.FTP下載文件
  • 12.HTTP
    • 13.WWW
  • 14.WWWForm
  • 15.UnityWebRequest
    • 15.1.常用上傳和獲取數據
    • 15.2.高級上傳和獲取數據
  • 16.Protobuf
    • 16.1.Protobuf配置規則
    • 16.2.Protobuf協議使用
        • 序列化存儲為本地文件
        • 反序列化本地文件
        • 得到序列化后的字節數組
        • 從字節數組反序列化
  • 17.大小端模式

1.網絡通信-通信必備知識-IP地址和端口類

分類詳情
IPAddress類

命名空間:System.Net
初始化方式
1. byte數組byte[] ipAddress = new byte[] { 118, 102, 111, 11 }; IPAddress iPAddress1 = new IPAddress(ipAddress);
2. long長整型IPAddress iPAddress2 = new IPAddress(0x76666F0B);(不建議使用)
3. 字符串轉換IPAddress iPAddress3 = IPAddress.Parse("118.102.111.11");(推薦)
特殊IP地址:127.0.0.1代表本機地址
靜態成員IPAddress.IPv6Any(獲取可用的IPv6地址)

IPEndPoint類

命名空間:System.Net
作用:將網絡端點表示為IP地址和端口號,用IP地址和端口號表示計算機的一個程序
初始化方式
1. long長整型IP和端口號IPEndPoint iPEndPoint1 = new IPEndPoint(0x79666F0B, 8080);
2. IP地址對象和端口號IPEndPoint iPEndPoint2 = new IPEndPoint(IPAddress.Parse("118.102.111.11"), 8080);(推薦)

IPHostEntry

作為域名解析返回值,用于獲取IP、主機名等信息。成員變量有:AddressList(獲取關聯IP)、Aliases(獲取主機別名列表)、HostName(獲取DNS名稱)

Dns

靜態類,提供根據域名獲取IP的方法。常用方法有:GetHostName(獲取本地主機名,如print(Dns.GetHostName());)、GetHostEntry(同步獲取IP,如IPHostEntry entry = Dns.GetHostEntry("www.baidu.com");)、GetHostEntryAsync(異步獲取IP,如Task<IPHostEntry> task = Dns.GetHostEntryAsync("www.baidu.com"); await task;

2.網絡通信中序列化和反序列化2進制數據

類名詳情
BitConverter

所在命名空間:System
1. GetBytes():將非字符串類型數據(如intshortbool等)轉換為字節數組,用于類對象二進制序列化時處理非字符串類型變量。
2. ToInt32()ToInt16()ToBoolean()等:將字節數組轉換為對應的非字符串類型數據(如intshortbool等),用于類對象二進制反序列化時將字節數組分組轉換為對應類型變量。

Encoding

所在命名空間:System.Text
1. UTF8.GetBytes():將字符串轉換為字節數組,在類對象二進制序列化時,先計算字符串字節數組長度并序列化,再序列化字符串實際內容。
2. UTF8.GetString():傳入字節數組、起始位置和長度,將字節數組轉換為字符串,在類對象二進制反序列化時,先讀取字符串字節數組長度,再根據長度和字節數組轉換為字符串。

3.Socket類

類名詳情
Socket

命名空間:System.Net.Sockets
作用:支持TCP/IP網絡通信的基本操作單位,是網絡通信的數據通道,包含本機與對方主機的IP地址和端口、雙方通信協議信息,可連接客戶端和服務端以收發消息。常用于長連接游戲的通信。
類型
1. 流套接字:用于TCP通信,提供面向連接、可靠、有序、無差錯且無重復的數據傳輸服務。
2. 數據報套接字:用于UDP通信,提供無連接通信服務,數據包長度不超32KB,不保證正確性和順序,可能重發、丟失。
3. 原始套接字:用于IP數據包通信,訪問協議較低層,用于偵聽和分析數據包(不常用)。
構造函數public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);
構造函數參數說明
1. AddressFamily:網絡尋址枚舉類型,常用InterNetwork(IPv4尋址)、InterNetwork6(IPv6尋址)。
2. SocketType:套接字枚舉類型,常用Dgram(用于UDP通信)、Stream(用于TCP通信)。
3. ProtocolType:協議類型枚舉類型,常用TCPUDP
常用搭配
1. SocketType.Dgram + ProtocolType.Udp:UDP協議通信。
2. SocketType.Stream + ProtocolType.Tcp:TCP協議通信。
實例化
1. TCP流套接字:Socket socketTcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
2. UDP數據報套接字:Socket socketUdp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
常用屬性
1. Connected:套接字的連接狀態。
2. SocketType:套接字的類型。
3. ProtocolType:套接字的協議類型。
4. AddressFamily:套接字的尋址方案。
5. Available:套接字可讀取字節數。
6. LocalEndPoint:本機EndPoint對象。
7. RemoteEndPoint:遠程EndPoint對象。
常用方法
服務端
1. Bind:綁定IP和端口,傳入IPEndPoint對象。
2. Listen:設置客戶端連接的最大數,傳入整形數字。
3. Accept:等待客戶端連入,返回一個Socket對象。
客戶端
1. Connect:連接遠程服務端,傳入IPEndPoint對象。
客戶端服務端通用
1. Shutdown:釋放連接并關閉Socket,選擇Both可同時防止發送和接收。
2. Close:關閉連接,釋放所有Socket關聯資源。
總結:TCP和UDP兩種長連接通信方案基于Socket套接字,需掌握TCP和UDP的Socket套接字聲明。

4.TCP同步服務端和客戶端基礎實現

4.1.服務端基本實現

(1)創建套接字Socket對象(TCP)

//1.創建套接字Socket(TCP)
Socket socketTcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

(2)用Bind方法將套接字與本地地址綁定

//2.用Bind方法將套接字與本地地址綁定
try
{IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);//把本機作為服務端程序 IP地址傳入本機socketTcp.Bind(iPEndPoint);//綁定
}
catch (Exception e)
{//如果IP地址不合法或者端口號被占用可能報錯Console.WriteLine("綁定報錯" + e.Message);return;
}

(3)用Listen方法監聽

//3.用Listen方法監聽
socketTcp.Listen(1024);//最大接收1024個客戶端
Console.WriteLine("服務端綁定監聽結束,等待客戶端連入");

(4)用Accept方法等待客戶端連接,建立連接,Accept返回新套接字

//5.建立連接,Accept返回新套接字
Socket socketClient = socketTcp.Accept();
//Accept是阻塞式的方法 會把主線程卡主 一定要等到客戶端接入后才會繼續執行后面的代碼
//客戶端接入后 返回新的Socket對象 這個新的Socket可以理解為客戶段和服務端的通信通道
Console.WriteLine("有客戶端連入了");

(5)用Send和Receive相關方法收發數據

//6.用Send和Receive相關方法收發數據
//發送字符串轉成的字節數組給客戶端
socketClient.Send(Encoding.UTF8.GetBytes("歡迎連入服務端"));
//聲明接受客戶端信息的字節數組 聲明1024容量代表能接受1kb的信息
byte[] result = new byte[1024];
//接受客戶端信息 返回值為接受到的字節數
int receiveNum = socketClient.Receive(result);
//打印 遠程發送信息的客戶端的IP和端口 以及 發送過來的字符串
Console.WriteLine("接受到了{0}發來的消息:{1}",socketClient.RemoteEndPoint.ToString(),Encoding.UTF8.GetString(result, 0, receiveNum));

(6)用Shutdown方法釋放連接

//7.用Shutdown方法釋放連接
//注意斷開的是客戶段和服務端的通信通道
socketClient.Shutdown(SocketShutdown.Both);

(7)關閉套接字

//8.關閉套接字
//注意關閉的是客戶段和服務端的通信通道
socketClient.Close();

4.2.客戶端實現:

(1)創建套接字Socket Tcp


Socket socketTcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

(2)用Connect方法與服務端相連

//確定服務端的IP和端口 正常來說填的應該是遠端服務器的ip地址以及端口號
//由于只有一臺電腦用于測試 本機也當做服務器 所以傳入當前電腦的ip地址
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
try
{//連接socketTcp.Connect(iPEndPoint);
}
catch (SocketException e)
{//如果連接沒有開啟或者服務器異常 會報錯 不同的返回碼代表不同報錯if (e.ErrorCode == 10061)print("服務器拒絕連接");elseprint("連接服務器失敗" + e.ErrorCode);return;
}

(3)用Send和Receive相關方法收發數據

//接收數據 
//聲明接收數據字節數組
byte[] receiveBytes = new byte[1024];
//Receive方法接受數據 返回接收多少字節
int receiveNum = socketTcp.Receive(receiveBytes);print("收到服務端發來的消息:" + Encoding.UTF8.GetString(receiveBytes, 0, receiveNum));//發送數據
socketTcp.Send(Encoding.UTF8.GetBytes("你好,我是韜老獅的客戶端"));

(4)用Shutdown方法釋放連接

//4.用Shutdown方法釋放連接
socketTcp.Shutdown(SocketShutdown.Both);

(5)關閉套接字

//5.關閉套接字
socketTcp.Close();

5.區分消息類型

為發送的信息添加標識,比如添加消息 ID。在所有發送的消息的頭部加上消息 ID(可以是 int、short、byte、long)。

舉例說明:
如果選用 int 類型作為消息 ID 的類型,前 4 個字節為消息 ID,后面的字節為數據類的內容,這樣每次收到消息時,先把前 4 個字節取出來解析為消息 ID,再根據 ID 進行消息反序列化即可。

6.分包和粘包

什么是分包、黏包?
分包、黏包指在網絡通信中由于各種因素(網絡環境、API規則等)造成的消息與消息之間出現的兩種狀態。
分包:一個消息分成了多個消息進行發送。
黏包:一個消息和另一個消息黏在了一起。
注意:分包和黏包可能同時發生。
解決思路:為消息添加頭部記錄長度,依據長度判斷并處理分包、黏包,僅處理完整消息。

7.TCP同步退出消息和心跳消息

7.1.客服端主動斷開連接

  1. 解決思路及主要修改邏輯
    • 客戶端:使用Disconnect方法主動斷開連接,在TcpNetManagerClose方法中,依次執行關閉套接字發送和接收、手動停止連接、關閉套接字連接、將套接字置空以及標記連接已關閉等操作。
    • 服務端
      • ServerSocket中添加CloseClientSocket方法,用于關閉客戶端連接并從字典中移除,操作客戶端對象字典時添加線程鎖以保證線程安全。
      • ServerSocket的其他操作或訪問字典的方法(如AcceptClientConnectReceiveClientMessageBroadcast)中添加線程鎖,確保字典操作的線程安全性。
      • 為避免在遍歷字典進行消息收發操作時直接移除客戶端導致報錯,在ServerSocket中創建List存儲待移除的客戶端socket(delList),并定義AddDelSocket方法用于添加待移除的socket。
      • ProgramserverSocket改為靜態變量,在ClientSocket的發送和接收消息方法中,檢測到斷開連接或解析報錯時,將當前客戶端添加到服務端待移除的客戶端列表中。

7.2.心跳消息

什么是心跳消息
所謂心跳消息,就是在長連接中,客戶端和服務端之間定期發送的一種特殊的數據包,用于通知對方自己還在線,以確保長連接的有效性。由于其發送的時間間隔往往是固定的持續的,就像是心跳一樣一直存在,所以我們稱之為心跳消息。
為什么需要心跳消息
避免非正常關閉客戶端時,服務器無法正常收到關閉連接消息。通過心跳消息我們可以自定義超時判斷,如果超時沒有收到客戶端消息,證明客戶端已經斷開連接。避免客戶端長期不發送消息,防火墻或者路由器會斷開連接,我們可以通過心跳消息一直保持活躍狀態。
實現心跳消息
客戶端:主要功能是定時發送消息。
服務器端:主要功能是不停檢測上次收到某客戶端消息的時間,如果超時則認為連接已經斷開。

8.Socket類TCP異步常用成員

類名方法參數詳情
SocketBeginAccept(AsyncCallback callback, object state)callback:處理異步接受客戶端連接操作完成時的回調函數;state:服務端Socket對象服務端開始接收客戶端的連接。
SocketEndAccept(IAsyncResult asyncResult)asyncResultBeginAccept方法返回的IAsyncResult對象服務端檢測到客戶端的連接結束,得到客戶端Socket
SocketBeginConnect(EndPoint remoteEP, AsyncCallback callback, object state)remoteEP:服務器的終結點(如IPEndPoint);callback:處理客戶端異步連接操作完成時的回調函數;state:客戶端的Socket對象客戶端異步連接到服務器。
SocketEndConnect(IAsyncResult asyncResult)asyncResultBeginConnect方法返回的IAsyncResult對象客戶端完成異步連接到服務器端的操作。
SocketBeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state)buffer:接收消息的字節數組;offset:從接收消息的字節數組第幾位開始存儲;size:字節數組長度;socketFlagsSocket標識;callback:接收消息回調函數;stateSocket對象開始接收消息。
SocketEndReceive(IAsyncResult asyncResult)asyncResultBeginReceive方法返回的IAsyncResult對象結束接收消息,返回接收的字節數組長度。
SocketBeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state)buffer:發送消息的字節數組;offset:從發送消息的字節數組第幾位開始發送;size:字節數組長度;socketFlagsSocket標識;callback:發送消息回調函數;stateSocket對象開始發送消息。
SocketEndSend(IAsyncResult asyncResult)asyncResultBeginSend方法返回的IAsyncResult對象結束發送消息,返回成功發送的字節數。
SocketAcceptAsync(SocketAsyncEventArgs e)eSocketAsyncEventArgs對象,用于處理異步接受客戶端連接操作完成后的操作服務端異步接受客戶端連接。
SocketConnectAsync(SocketAsyncEventArgs e)eSocketAsyncEventArgs對象,用于處理異步連接到服務器操作完成后的操作客戶端異步連接到服務器。
SocketSendAsync(SocketAsyncEventArgs e)eSocketAsyncEventArgs對象,設置好發送數據的緩沖區等信息,用于處理異步發送消息操作完成后的操作異步發送消息。
SocketReceiveAsync(SocketAsyncEventArgs e)eSocketAsyncEventArgs對象,設置好接收數據的緩沖區等信息,用于處理異步接受消息操作完成后的操作異步接受消息。

9.UDP

實現UDP客戶端通信收發字符串

//1.創建套接字 尋址類型還是Ipv4 Soket類型使用數據包 協議選擇Udp
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);//2.綁定本機地址 注意模擬測試時客戶端本機和服務端遠程機的端口號不能一樣
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
socket.Bind(ipPoint);//3.發送到指定目標 注意模擬測試時客戶端本機和服務端遠程機的端口號不能一樣
IPEndPoint remoteIpPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8081);
//指定要發送的字節數 和 遠程計算機的 IP和端口
socket.SendTo(Encoding.UTF8.GetBytes("韜老獅來了"), remoteIpPoint);//4.接受消息
//裝接收消息的字節數組
byte[] bytes = new byte[512];
//裝接收消息的IP地址和端口的對象 在ReceiveFrom方法會使用ref賦值 主要是用來記錄 誰發的信息給你 傳入函數后 在內部 它會幫助我們進行賦值
EndPoint remoteIpPoint2 = new IPEndPoint(IPAddress.Any, 0);
//接收消息 得到消息長度
int length = socket.ReceiveFrom(bytes, ref remoteIpPoint2);
print("IP:" + (remoteIpPoint2 as IPEndPoint).Address.ToString() +"port:" + (remoteIpPoint2 as IPEndPoint).Port +"發來了" +Encoding.UTF8.GetString(bytes, 0, length));//5.釋放關閉
socket.Shutdown(SocketShutdown.Both);
socket.Close();

實現UDP服務端通信收發字符串

//1.創建套接字 尋址類型還是Ipv4 Soket類型使用數據包 協議選擇Udp
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);//2.綁定本機地址 注意模擬測試時客戶端本機和服務端遠程機的端口號不能一樣
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8081);
socket.Bind(ipPoint);
Console.WriteLine("服務器開啟");//3.接受消息
//裝接收消息的字節數組
byte[] bytes = new byte[512];
//裝接收消息的IP地址和端口的對象 在ReceiveFrom方法會使用ref賦值 主要是用來記錄 誰發的信息給你 傳入函數后 在內部 它會幫助我們進行賦值
EndPoint remoteIpPoint2 = new IPEndPoint(IPAddress.Any, 0);
int length = socket.ReceiveFrom(bytes, ref remoteIpPoint2);
Console.WriteLine("IP:" + (remoteIpPoint2 as IPEndPoint).Address.ToString() +"port:" + (remoteIpPoint2 as IPEndPoint).Port +"發來了" +Encoding.UTF8.GetString(bytes, 0, length));//4.發送到指定目標
//由于服務端先收了消息 所以服務端已經知道誰發了消息給服務端 是使用remoteIpPoint2記錄的 服務端直接發給它就行了
socket.SendTo(Encoding.UTF8.GetBytes("歡迎發送消息給服務器"), remoteIpPoint2);//5.釋放關閉
socket.Shutdown(SocketShutdown.Both);
socket.Close();

10.Socket類UDP異步常用方法

類名方法參數詳情
SocketBeginSendTo(byte[] buffer, int offset, int size, SocketFlags socketFlags, EndPoint remoteEP, AsyncCallback callback, object state)buffer:要發送的數據字節數組;offset:從字節數組的哪個位置開始發送;size:發送數據的長度;socketFlagsSocketFlags標識;remoteEP:目標IP和端口號;callback:回調函數;state:回調函數的參數開始向指定IP和端口異步發送數據,將結果異步傳回回調函數進行處理
SocketEndSendTo(IAsyncResult asyncResult)asyncResultBeginSendTo方法返回的IAsyncResult對象結束異步發送操作
SocketBeginReceiveFrom(byte[] buffer, int offset, int size, SocketFlags socketFlags, ref EndPoint remoteEP, AsyncCallback callback, object state)buffer:緩存區;offset:緩存區的起始位置;size:最大接收數據長度;socketFlagsSocketFlags標識;remoteEP:接收數據的來源IPEndPointcallback:回調函數;state:回調函數的參數開始異步從UDP客戶端接收數據,將接收到的數據放入緩存區,接收數據的來源ip和端口號會被保存,有數據到達時調用回調函數處理
SocketEndReceiveFrom(IAsyncResult asyncResult, ref EndPoint remoteEP)asyncResultBeginReceiveFrom方法返回的IAsyncResult對象;remoteEP:接收數據的來源IPEndPoint結束異步接收操作,并返回接收到的字節數
SocketSendToAsync(SocketAsyncEventArgs e)eSocketAsyncEventArgs對象,設置好要發送的數據、目標IP地址等信息開始向指定IP和端口發送數據,發送完成后在回調函數處理
SocketReceiveFromAsync(SocketAsyncEventArgs e)eSocketAsyncEventArgs對象,設置好接收數據的緩沖區、接收來源的IPEndPoint等信息開始異步從UDP客戶端接收數據,接收完成后在回調函數進行處理

11.FTP

類名用途/功能重要方法重要成員
NetworkCredentialSystem.Net在網絡身份驗證中存儲用戶名和密碼信息,用于 FTP 文件傳輸場景下提供訪問 FTP 服務器所需的認證憑據
FtpWebRequestSystem.Net用于執行上傳、下載、刪除 FTP 服務器上的文件等操作1. Create:創建新 Ftp 請求。
2. Abort:終止 Ftp 傳輸。
3. GetRequestStream:獲取用于上傳的流。
4. GetResponse:返回 FTP 服務器響應。
1. Credentials:設置通信憑證為NetworkCredential對象。
2. KeepAlive:設置完成請求時是否關閉到 FTP 服務器的控制連接。
3. Method:設置 FTP 請求操作命令,如刪除、下載、列目錄等。
4. UseBinary:指定是否采用二進制模式傳輸數據。
5. RenameTo:重命名文件。
FtpWebResponseSystem.Net封裝 FTP 服務器對請求的響應,提供操作狀態及從服務器下載的數據,用于表示響應信息,含響應代碼、消息等1. Close:釋放所有資源。
2. GetResponseStream:返回從 FTP 服務器下載數據的流。
1. ContentLength:接收到數據的長度。
2. ContentType:接收數據的類型。
3. StatusCode:FTP 服務器下發的最新狀態碼。
4. StatusDescription:狀態代碼的文本描述。
5. BannerMessage:登錄前建立連接時服務器發送的消息。
6. ExitMessage:獲取 FTP 會話結束時服務器發送的消息。
7. LastModified:獲取 FTP 服務器上文件的最后修改日期和時間。

11.1.FTP上傳文件

try
{// 創建一個Ftp連接,pic.png代表想上傳名叫pic的png圖片。// 這里的ftp://127.0.0.1是使用本機開啟服務器進行測試,實際使用時應該是遠端服務器IP。FtpWebRequest ftpWebRequest = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/pic.png")) as FtpWebRequest;// 設置通信憑證(如果不支持匿名,就必須設置這一步)。// 將代理相關信息置空,避免服務器同時有http相關服務造成沖突。ftpWebRequest.Proxy = null;// 創建并設置通信憑證。NetworkCredential networkCredential = new NetworkCredential("MrTao", "MrTao");ftpWebRequest.Credentials = networkCredential;// 請求完畢后是否關閉控制連接,如果想要關閉,可以設置為false。ftpWebRequest.KeepAlive = false;// 設置操作命令。ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile;//設置命令操作為上傳文件。// 指定傳輸類型,使用二進制。ftpWebRequest.UseBinary = true;// 得到用于上傳的流對象。Stream uploadRequestStream = ftpWebRequest.GetRequestStream();// 開始上傳,使用流讀取StreamingAssets文件夾下的名叫test的圖片。using (FileStream fileStream = File.OpenRead(Application.streamingAssetsPath + "/test.png")){// 我們可以一點一點的把這個文件中的字節數組讀取出來,然后存入到上傳流中。byte[] bytes = new byte[1024];// 返回值是真正從文件中讀了多少個字節。int contentLength = fileStream.Read(bytes, 0, bytes.Length);// 不停的去讀取文件中的字節,除非讀取完畢了,不然一直讀,并且寫入到上傳流中。while (contentLength != 0){// 寫入上傳流中。uploadRequestStream.Write(bytes, 0, contentLength);// 寫完了繼續讀。contentLength = fileStream.Read(bytes, 0, bytes.Length);}// 出了循環就證明寫完了。fileStream.Close();uploadRequestStream.Close();// 上傳完畢。print("上傳結束");}
}
catch (Exception e)
{print("上傳出錯,失敗" + e.Message);
}

11.2.FTP下載文件

try
{// 創建一個Ftp連接。// 這里和上傳不同,上傳的文件名是自己定義的,下載的文件名一定是資源服務器上有的,比如一張叫pic的圖片。FtpWebRequest ftpWebRequest = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/pic.png")) as FtpWebRequest;// 設置通信憑證(如果不支持匿名,就必須設置這一步)。ftpWebRequest.Credentials = new NetworkCredential("MrTao", "MrTao");// 請求完畢后是否關閉控制連接,如果要進行多次操作,可以設置為false。ftpWebRequest.KeepAlive = false;// 設置操作命令。ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile;// 指定傳輸類型。ftpWebRequest.UseBinary = true;// 代理設置為空。ftpWebRequest.Proxy = null;// 得到用于下載的流對象。// 相當于把請求發送給FTP服務器,返回值就會攜帶我們想要的信息。FtpWebResponse ftpWebResponse = ftpWebRequest.GetResponse() as FtpWebResponse;// 這就是下載的流。Stream downloadResponseStream = ftpWebResponse.GetResponseStream();// 開始下載。print(Application.persistentDataPath);using (FileStream fileStream = File.Create(Application.persistentDataPath + "/pic2.png")){// 讀取流的字節數組。byte[] bytes = new byte[1024];// 讀取下載下來的流數據。int contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);// 一點一點的下載到本地流中。while (contentLength != 0){// 把讀取出來的字節數組寫入到本地文件流中。fileStream.Write(bytes, 0, contentLength);// 繼續讀。contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);}// 下載結束,關閉流。downloadResponseStream.Close();fileStream.Close();}print("下載結束");
}
catch (Exception e)
{print("下載出錯" + e.Message);
}

12.HTTP

類名(命名空間)用途重要方法重要成員
HttpWebRequest(System.Net)用于向服務器發送HTTP客戶端請求,進行消息通信、上傳、下載等操作1. Create:創建新的WebRequest,用于HTTP相關操作
2. Abort:終止文件傳輸
3. GetRequestStream:獲取用于上傳的流
4. GetResponse:返回HTTP服務器響應
5. Begin/EndGetRequestStream:異步獲取用于上傳的流
6. Begin/EndGetResponse:異步獲取返回的HTTP服務器響應
1. Credentials:通信憑證,設置為NetworkCredential對象
2. PreAuthenticate:是否隨請求發送一個身份驗證標頭,一般需身份驗證時設為true
3. Headers:構成標頭的名稱/值對的集合
4. ContentLength:發送信息的字節數,上傳信息時需先設置
5. ContentType:POST請求時,需對發送內容進行內容類型設置
6. Method:操作命令設置,如Get、Post、Head等
HttpWebResponse(System.Net)用于獲取服務器反饋信息,通過HttpWebRequest對象的GetResponse()方法獲取,使用完畢用Close釋放1. Close:釋放所有資源
2. GetResponseStream:返回從FTP服務器下載數據的流
1. ContentLength:接受到數據的長度
2. ContentType:接受數據的類型
3. StatusCode:HTTP服務器下發的最新狀態碼
4. StatusDescription:HTTP服務器下發的狀態代碼的文本
5. BannerMessage:登錄前建立連接時HTTP服務器發送的消息
6. ExitMessage:HTTP會話結束時服務器發送的消息
7. LastModified:HTTP服務器上的文件的上次修改日期和時間
NetworkCredential、Uri、Stream、FileStream(相關命名空間)在HTTP通訊時使用方式與FTP類似--

13.WWW

類名(命名空間)作用常用方法常用變量
WWW(UnityEngine)用于簡單訪問網頁,可進行數據的下載和上傳。使用 HTTP 協議時默認請求類型是 Get,進行 Post 上傳需配合 WWWForm 類1. WWW:構造函數,用于創建一個 WWW 請求
2. GetAudioClip:從下載數據返回一個音效切片 AudioClip 對象
3. LoadImageIntoTexture:用下載數據中的圖像來替換現有的一個 Texture2D 對象
4. LoadFromCacheOrDownload:從緩存加載 AB 包對象,如果該包不在緩存則自動下載存儲到緩存中,以便以后直接從本地緩存中加載
1. assetBundle:如果加載的數據是 AssetBundle,則可直接獲取加載結果
2. audioClip:如果加載的數據是音效切片文件,可直接獲取加載結果(新版本用 GetAudioClip 方法)
3. bytes:以字節數組形式獲取加載內容
4. bytesDownloaded:已下載的字節數
5. error:下載出錯時返回錯誤消息
6. isDone:判斷下載是否完成
7. movie:下載視頻時可獲取 MovieTexture 類型結果(新版本用 GetMovieTexture 方法)
8. progress:下載進度
9. text:下載數據為字符串時,以字符串形式返回內容
10. texture:下載數據為圖片時,以 Texture2D 形式返回加載結果

14.WWWForm

類名作用注意事項常用方法
WWWForm在使用 WWW 類下載數據的基礎上,若需上傳數據,可結合該類使用。主要用于集成數據,可設置上傳的參數或者二進制數據,結合使用時主要用 Post 請求類型,通過 Http 協議上傳處理使用 WWW 結合 WWWForm 上傳數據通常需要與后端程序制定上傳規則1. WWWForm:構造函數
2. AddBinaryData:添加二進制數據
3. AddField:添加字段

15.UnityWebRequest

15.1.常用上傳和獲取數據

獲取

類名方法方法解析參數
UnityWebRequestGet創建一個用于獲取文本或二進制數據的 UnityWebRequest 對象。uri:請求資源的 URI 地址,如 "http://192.168.1.101:8000/HTTPRoot/test.txt"
UnityWebRequestTextureGetTexture創建一個用于獲取紋理數據的 UnityWebRequest 對象。uri:請求紋理資源的 URI 地址,可以是 httpftpfile 協議的地址,如 "http://192.168.1.101:8000/HTTPRoot/pic.png""ftp://127.0.0.1/pic.png""file://" + Application.streamingAssetsPath + "/test.png"
UnityWebRequestAssetBundleGetAssetBundle創建一個用于獲取 AB 包數據的 UnityWebRequest 對象。uri:請求 AB 包資源的 URI 地址,如 "http://192.168.1.101:8000/HTTPRoot/model"
UnityWebRequestSendWebRequest發送 Web 請求并等待服務器響應。
DownloadHandlerTextureGetContentUnityWebRequest 對象中獲取下載的紋理數據。requestUnityWebRequest 對象,用于獲取其中的紋理數據
DownloadHandlerAssetBundleGetContentUnityWebRequest 對象中獲取下載的 AB 包數據。requestUnityWebRequest 對象,用于獲取其中的 AB 包數據

上傳

類名/接口方法/描述參數
IMultipartFormSection數據相關類繼承的父接口,可使用父類類型的集合來存儲子類對象
MultipartFormDataSection用于傳遞鍵值對數據的類

1. 構造函數(二進制字節數組):MultipartFormDataSection(byte[] data),參數data為二進制字節數組
2. 構造函數(字符串):MultipartFormDataSection(string data),參數data為字符串
3. 構造函數(參數名,參數值,編碼類型,資源類型):MultipartFormDataSection(string name, string data, Encoding encoding, string contentType),參數name為參數名,data為參數值(字符串或字節數組形式),encoding為編碼類型,contentType為資源類型
4. 構造函數(參數名,字節數組,資源類型):MultipartFormDataSection(string name, byte[] data, string contentType),參數name為參數名,data為字節數組,contentType為資源類型

MultipartFormFileSection用于傳遞文件數據的類

1. 構造函數(字節數組):MultipartFormFileSection(byte[] data),參數data為字節數組
2. 構造函數(文件名,字節數組):MultipartFormFileSection(string fileName, byte[] data),參數fileName為文件名,data為字節數組
3. 構造函數(字符串數據,文件名):MultipartFormFileSection(string data, string fileName),參數data為字符串數據,fileName為文件名
4. 構造函數(字符串數據,編碼格式,文件名):MultipartFormFileSection(string data, Encoding encoding, string fileName),參數data為字符串數據,encoding為編碼格式,fileName為文件名
5. 構造函數(表單名,字節數組,文件名,文件類型):MultipartFormFileSection(string formName, byte[] data, string fileName, string contentType),參數formName為表單名,data為字節數組,fileName為文件名,contentType為文件類型
6. 構造函數(表單名,字符串數據,編碼格式,文件名):MultipartFormFileSection(string formName, string data, Encoding encoding, string fileName),參數formName為表單名,data為字符串數據,encoding為編碼格式,fileName為文件名

UnityWebRequestPost方法:創建一個用于使用 POST 請求上傳數據的UnityWebRequest對象
Put方法:創建一個用于使用 PUT 請求上傳數據的UnityWebRequest對象
SendWebRequest方法:發送 Web 請求并等待服務器響應

1. Post方法:UnityWebRequest.Post(string uri, List<IMultipartFormSection> formData),參數uri為請求的 URI 地址,formData為包含上傳數據的IMultipartFormSection列表
2. Put方法:UnityWebRequest.Put(string uri, byte[] data),參數uri為請求的 URI 地址,data為要上傳的文件內容(字節數組形式)
3. SendWebRequest方法:無參數

NetWWWManagerUploadFile方法:啟動異步上傳文件的操作
UploadFileAsync方法:異步上傳文件的具體實現

1. UploadFile方法:UploadFile(string fileName, string localPath, UnityAction<UnityWebRequest.Result> action),參數fileName為上傳后的文件名,localPath為本地要上傳文件的路徑,action為上傳完成后的回調函數
2. UploadFileAsync方法:UploadFileAsync(string fileName, string localPath, UnityAction<UnityWebRequest.Result> action),參數fileName為上傳后的文件名,localPath為本地要上傳文件的路徑,action為上傳完成后的回調函數

15.2.高級上傳和獲取數據

獲取

類名方法/屬性方法的參數
UnityWebRequest構造函數
UnityWebRequesturl字符串類型的服務器地址
UnityWebRequestmethod如UnityWebRequest.kHttpVerbPOST等請求類型常量
UnityWebRequesttimeout整數類型的超時時間(單位:毫秒)
UnityWebRequestredirectLimit整數類型,0表示不進行重定向
UnityWebRequestresponseCode
UnityWebRequestresult
UnityWebRequesterror
UnityWebRequestdownloadHandler實現了DownloadHandler的對象,如DownloadHandlerBuffer等
UnityWebRequestuploadHandler實現了UploadHandler的對象
UnityWebRequestGet字符串類型的請求URL
UnityWebRequestGetTexture字符串類型的紋理URL
UnityWebRequestAssetBundleGetAssetBundle字符串類型的AssetBundle URL
UnityWebRequestPut字符串類型的請求URL和字節數組形式的上傳內容
UnityWebRequestPost字符串類型的請求URL和List類型的上傳數據列表
UnityWebRequestisDone
UnityWebRequestdownloadProgress
UnityWebRequestdownloadedBytes
UnityWebRequestuploadProgress
UnityWebRequestuploadedBytes
UnityWebRequestSendWebRequest
DownloadHandlerBuffer構造函數
DownloadHandlerFile構造函數字符串類型的本地文件保存路徑
DownloadHandlerTexture構造函數
DownloadHandlerAssetBundle構造函數字符串類型的請求URL和校驗碼(ulong類型,不知道則傳入0)
UnityWebRequestMultimediaGetAudioClip字符串類型的音頻文件URL和AudioType類型的音頻類型
DownloadHandlerAudioClipGetContentUnityWebRequest對象
CustomDownLoadFileHandler構造函數(無參)
CustomDownLoadFileHandler構造函數(字節數組)字節數組類型的參數
CustomDownLoadFileHandler構造函數(路徑)字符串類型的本地存儲路徑
CustomDownLoadFileHandlerGetData
CustomDownLoadFileHandlerReceiveDatabyte[]類型的數據和int類型的數據長度
CustomDownLoadFileHandlerReceiveContentLengthHeaderulong類型的內容長度
CustomDownLoadFileHandlerCompleteContent

上傳

類名方法/屬性方法的參數描述
UnityWebRequest構造函數string uri, string method:請求的 URL 和 HTTP 請求方法(如 UnityWebRequest.kHttpVerbPOST創建一個 UnityWebRequest 對象,用于網絡請求
UnityWebRequestuploadHandler實現了 UploadHandler 的對象,如 UploadHandlerRawUploadHandlerFile設置上傳處理對象,用于處理上傳的數據
UnityWebRequestSendWebRequest發送網絡請求,并等待請求返回
UnityWebRequestresult獲取網絡請求的結果(成功或失敗)
UploadHandlerRaw構造函數byte[] data:要上傳的字節數組創建一個用于上傳字節數組的 UploadHandlerRaw 對象
UploadHandlerRawcontentTypestring 類型的內容類型,如 "類型/細分類型"設置上傳數據的內容類型,若不設置,默認是 application/octet - stream
UploadHandlerFile構造函數string path:要上傳的文件路徑創建一個用于上傳文件的 UploadHandlerFile 對象

16.Protobuf

16.1.Protobuf配置規則

(1)配置文件后綴:統一使用.proto,可通過多個該后綴文件配置。
(2)版本號:第一行需指定,如syntax = "proto3";,不寫默認用proto2。
(3)注釋方式:支持//單行注釋和/* */多行注釋。
(4)命名空間:用package指定,如package 命名空間名;
(5)消息類:使用message定義,格式為message 類名 { // 字段聲明 }
(6)成員類型和編號:成員類型包含浮點數(floatdouble )、整數(int32int64等)、其他(boolstringbytes ),每個成員需指定從1開始的唯一編號。
(7)特殊標識:optional表示可選賦值字段;repeated表示數組(required在proto3中已移除 )。
(8)枚舉:用enum定義,首個常量必須為0,如enum 枚舉名 { 常量1 = 0; 常量2 = 1; }
(9)默認值:string為空字符串、bytes為空字節、boolfalse、數值為0、枚舉為0、message在C#中為空。
(10)嵌套:支持消息類和枚舉的嵌套定義。
(11)保留字段:使用reserved關鍵字保留字段,防止已刪編號被重新使用。
(12)導入定義:若使用其他配置中的類型,用import "配置文件路徑";導入。

syntax = "proto3"; // 決定了 proto 文檔的版本號// 規則1:版本號// 規則2:注釋方式
// 注釋方式一
/* 注釋方式二 */// 規則11:導入定義
// 兩個配置在同一路徑可以這樣寫,在不同路徑要包含文件夾路徑
import "test2.proto";// 規則3:命名空間
package GamePlayerTest; // 這決定了命名空間// 規則4:消息類
message TestMsg {// 規則5:成員類型 和 唯一編號// 浮點數// = 1 不代表默認值,而是代表唯一編號,方便我們進行序列化和反序列化的處理// 規則6:特殊標識// required: 必須賦值的字段required float testF = 1; // C# - float// optional: 可以不賦值的字段optional double testD = 2; // C# - double// 變長編碼// 所謂變長,就是會根據數字的大小來使用對應的字節數來存儲,1 2 4// Protobuf 幫助我們優化的部分,可以盡量少的使用字節數來存儲內容int32 testInt32 = 3; // C# - int 它不太適用于來表示負數,請使用 sint32// 1 2 4 8int64 testInt64 = 4; // C# - long 它不太適用于來表示負數,請使用 sint64// 更實用與表示負數類型的整數sint32 testSInt32 = 5; // C# - int 適用于來表示負數的整數sint64 testSInt64 = 6; // C# - long 適用于來表示負數的整數// 無符號 變長編碼// 1 2 4uint32 testUInt = 7; // C# - uint 變長的編碼uint64 testULong = 8; // C# - ulong 變長的編碼// 固定字節數的類型fixed32 testFixed32 = 9; // C# - uint 它通常用來表示大于2的28次方的數,比 uint32 更有效,始終是4個字節fixed64 testFixed64 = 10; // C# - ulong 它通常用來表示大于2的56次方的數,比 uint64 更有效,始終是8個字節sfixed32 testSFixed32 = 11; // C# - int 始終4個字節sfixed64 testSFixed64 = 12; // C# - long 始終8個字節// 其它類型bool testBool = 13; // C# - boolstring testStr = 14; // C# - stringbytes testBytes = 15; // C# - BytesString 字節字符串// 數組 Listrepeated int32 listInt = 16; // C# - 類似 List<int> 的使用// 字典 Dictionarymap<int32, string> testMap = 17; // C# - 類似 Dictionary<int, string> 的使用// 規則7:枚舉// 枚舉成員變量的聲明需要唯一編碼TestEnum testEnum = 18;// 規則8:默認值// 聲明自定義類對象 需要唯一編碼// 默認值是 nullTestMsg2 testMsg2 = 19;// 規則9:允許嵌套// 嵌套一個類在另一個類當中,相當于是內部類message TestMsg3 {int32 testInt32 = 1;}TestMsg3 testMsg3 = 20;// 規則9:允許嵌套enum TestEnum2 {NORMAL = 0; // 第一個常量必須映射到0BOSS = 1;}TestEnum2 testEnum2 = 21;// 規則10:保留字段// int32 testInt3233333 = 22;bool testBool2123123 = 23;// 告訴編譯器 22 被占用,不準用戶使用// 之所以有這個功能,是為了在版本不匹配時,反序列化時,不會出現結構不統一,解析錯誤的問題reserved 22;reserved testInt3233333;// 規則11:導入定義GameSystemTest.HeartMsg testHeart = 24;
}// 規則7:枚舉的聲明
enum TestEnum {NORMAL = 0; // 第一個常量必須映射到0BOSS = 5;
}// 規則8:默認值
message TestMsg2 {int32 testInt32 = 1;
}syntax = "proto3"; // 決定了 proto 文檔的版本號
package GameSystemTest; // 這決定了命名空間message HeartMsg {int64 time = 1;
}

16.2.Protobuf協議使用

序列化存儲為本地文件
  • 主要使用方法:生成的類中的 WriteTo 方法和文件流 FileStream 對象。
  • 示例代碼
TestMsg testMsg1 = new TestMsg();
testMsg1.ListInt.Add(1);
testMsg1.TestBool = false;
testMsg1.TestD = 5.5;
testMsg1.TestInt32 = 99;
testMsg1.TestMap.Add(1, "楊");
testMsg1.TestMsg2 = new TestMsg2();
testMsg1.TestMsg2.TestInt32 = 88;
testMsg1.TestMsg3 = new TestMsg.Types.TestMsg3();
testMsg1.TestMsg3.TestInt32 = 66;testMsg1.TestHeart = new GameSystemTest.HeartMsg();
testMsg1.TestHeart.Time = 7777;print(Application.persistentDataPath);
using (FileStream fileStream = File.Create(Application.persistentDataPath + "/TestMsg.tao"))
{testMsg1.WriteTo(fileStream);
}
  • 代碼解釋:先創建 TestMsg 實例并設置其屬性值,然后使用 File.Create 方法創建一個文件流,將 TestMsg 實例序列化后寫入該文件流,實現數據的本地存儲。
反序列化本地文件
  • 主要使用方法:生成的類中的 Parser.ParseFrom 方法和文件流 FileStream 對象。
  • 示例代碼
using (FileStream fileStream = File.OpenRead(Application.persistentDataPath + "/TestMsg.tao"))
{TestMsg testMsg2 = null;testMsg2 = TestMsg.Parser.ParseFrom(fileStream);print(testMsg2.TestMap[1]);print(testMsg2.ListInt[0]);print(testMsg2.TestD);print(testMsg2.TestMsg2.TestInt32);print(testMsg2.TestMsg3.TestInt32);print(testMsg2.TestHeart.Time);
}
  • 代碼解釋:使用 File.OpenRead 方法打開之前存儲的文件流,然后調用 Parser.ParseFrom 方法從文件流中反序列化出 TestMsg 實例,最后打印該實例的屬性值。
得到序列化后的字節數組
  • 主要使用方法:生成的類中的 WriteTo 方法和內存流 MemoryStream 對象。
  • 示例代碼
byte[] bytes = null;
using (MemoryStream memoryStream = new MemoryStream())
{testMsg1.WriteTo(memoryStream);bytes = memoryStream.ToArray();print("字節數組長度" + bytes.Length);
}
  • 代碼解釋:創建一個內存流,將 TestMsg 實例序列化后寫入該內存流,再通過 ToArray 方法將內存流中的數據轉換為字節數組,方便進行網絡傳輸。
從字節數組反序列化
  • 主要使用方法:生成的類中的 Parser.ParseFrom 方法和內存流 MemoryStream 對象。
  • 示例代碼
using (MemoryStream memoryStream = new MemoryStream(bytes))
{print("內存流當中反序列化的內容");TestMsg testMsg2 = TestMsg.Parser.ParseFrom(memoryStream);print(testMsg2.TestMap[1]);print(testMsg2.ListInt[0]);print(testMsg2.TestD);print(testMsg2.TestMsg2.TestInt32);print(testMsg2.TestMsg3.TestInt32);print(testMsg2.TestHeart.Time);
}
  • 代碼解釋:使用包含字節數組的內存流,調用 Parser.ParseFrom 方法從內存流中反序列化出 TestMsg 實例,最后打印該實例的屬性值。

17.大小端模式

(1)大小端模式的基本概念

  1. 大端模式:數據的高字節保存在內存的低地址中,低字節保存在內存的高地址中。地址由小向大增加時,數據從高位往低位放置,類似字符串順序處理,符合人類閱讀習慣。
  2. 小端模式:數據的高字節保存在內存的高地址中,低字節保存在內存的低地址中。例如十六進制數據 0x11223344,大端模式存儲為 11 22 33 44(地址 0 1 2 3),小端模式存儲為 44 33 22 11(地址 0 1 2 3)。
  3. 存在原因:是計算機硬件的兩種存儲數據方式(字節序)。計算機內部處理按順序讀取字節,因處理低位字節效率高而采用小端模式,人類讀寫習慣是大端字節序,網絡傳輸和文件存儲等場合一般用大端模式。

(2)大小端模式的影響及轉換

  1. 影響:只有讀取數據時需區分大小端字節序。網絡傳輸中,前后端語言和設備差異可能致大小端不統一,如 C# 和 Java/Erlang/AS3 通訊需轉換,C# 與 C++ 通信通常無需特殊處理。
  2. 轉換方法
    • 判斷模式:用 BitConverter.IsLittleEndian 判斷,如 print("是否是小端模式:" + BitConverter.IsLittleEndian);
    • 轉為大端模式:通過 IPAddress.HostToNetworkOrder 將本機字節序轉網絡字節序(即大端模式),如 int i = 99; byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i));
    • 轉為小端模式:用 IPAddress.NetworkToHostOrder 將網絡字節序轉本機字節序(即小端模式),如 int receI = BitConverter.ToInt32(bytes, 0); receI = IPAddress.NetworkToHostOrder(receI);
    • 倒序數組轉換:使用 Array.Reverse 倒序數組,若后端需大端模式且當前是小端模式則轉換,如 if (BitConverter.IsLittleEndian) Array.Reverse(bytes);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73221.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73221.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73221.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

內網滲透技術 Docker逃逸技術(提權)研究 CSMSF

目錄 如何通過上傳的webshell判斷當前環境是否是物理環境還是Docker環境 方法一&#xff1a;檢查文件系統 方法二&#xff1a;查看進程 方法三&#xff1a;檢查網絡配置 方法四&#xff1a;檢查環境變量 方法五&#xff1a;檢查掛載點 總結 2. 如果是Docker環境&#x…

動態規劃:從暴力遞歸到多維優化的算法進化論(C++實現)

動態規劃&#xff1a;從暴力遞歸到多維優化的算法進化論 一、動態規劃的本質突破 動態規劃&#xff08;Dynamic Programming&#xff09;不是簡單的遞歸優化&#xff0c;而是計算思維范式的革命性轉變。其核心價值在于通過狀態定義和決策過程形式化&#xff0c;將指數復雜度問…

數據結構與算法-數據結構-樹狀數組

概念 樹狀數組&#xff0c;也叫二叉索引樹&#xff08;Binary Indexed Tree&#xff0c;BIT&#xff09;&#xff0c;它是用數組來模擬樹形結構。樹狀數組的每個節點存儲的是數組中某一段的和&#xff08;或其他可合并的信息&#xff09;&#xff0c;通過巧妙的索引方式和樹形…

AI比人腦更強,因為被植入思維模型【19】三腦理論思維模型

定義 三腦理論思維模型是由美國神經科學家保羅麥克萊恩&#xff08;Paul MacLean&#xff09;提出的&#xff0c;該理論認為人類的大腦由三個不同但又相互關聯的部分組成&#xff0c;分別是爬蟲腦&#xff08;Reptilian Brain&#xff09;、邊緣腦&#xff08;Limbic Brain&am…

使用 patch-package 優雅地修改第三方依賴庫

在前端開發中&#xff0c;有時我們需要對第三方依賴庫進行修改以滿足項目需求。然而&#xff0c;直接修改 node_modules 中的文件并不是一個好方法&#xff0c;因為每次重新安裝依賴時這些修改都會丟失。patch-package 是一個優秀的工具&#xff0c;可以幫助我們優雅地管理這些…

馬科維茨均值—方差理論推導過程

下面給出一個詳細的、符號嚴謹、公式連貫的馬科維茨均值—方差理論推導過程&#xff0c;假設你輸入了 nnn 列股票的歷史收盤價數據。我們從數據符號的定義開始&#xff0c;逐步構建所有公式&#xff0c;并詳細解釋每個符號的意義。

僅靠prompt,Agent難以自救

Alexander的觀點很明確&#xff1a;未來 AI 智能體的發展方向還得是模型本身&#xff0c;而不是工作流&#xff08;Work Flow&#xff09;。還拿目前很火的 Manus 作為案例&#xff1a;他認為像 Manus 這樣基于「預先編排好的提示詞與工具路徑」構成的工作流智能體&#xff0c;…

【css酷炫效果】純CSS實現懸浮彈性按鈕

【css酷炫效果】純CSS實現懸浮彈性按鈕 緣創作背景html結構css樣式完整代碼效果圖 想直接拿走的老板&#xff0c;鏈接放在這里&#xff1a;https://download.csdn.net/download/u011561335/90492020 緣 創作隨緣&#xff0c;不定時更新。 創作背景 剛看到csdn出活動了&…

決策樹基礎

決策樹 定義 從根節點開始&#xff0c;也就是擁有全部的數據&#xff0c;找一個維度對根節點開始劃分&#xff0c; 劃分后希望數據整體的信息熵是最小的&#xff0c; 針對劃分出來的兩個節點&#xff0c;我們繼續重復剛才的劃分方式尋找信息熵最小的維度和閾值。 遞歸這個…

動態查找表

1.問題分析&#xff1a; 動態查找表是一種可以動態地插入、刪除和查找元素的數據結構。它是基于二叉搜索樹實現的&#xff0c;具有快速的查找和插入操作。 以下是一些關于動態查找表的問題分析&#xff1a; 1. 插入操作&#xff1a;在動態查找表中插入一個元素時&#xff0c…

得分匹配的朗之萬動力學——Score-Matching Langevin Dynamics (SMLD)

得分匹配的朗之萬動力學——Score-Matching Langevin Dynamics (SMLD) 文章目錄 得分匹配的朗之萬動力學——Score-Matching Langevin Dynamics (SMLD)摘要Abstract周報內容0. 上期補充1. 本期的基本思想2. 從一個分布中采樣&#xff08;Sampling from a Distribution&#xff…

字節DAPO算法:改進DeepSeek的GRPO算法-解鎖大規模LLM強化學習的新篇章(代碼實現)

DAPO算法&#xff1a;解鎖大規模LLM強化學習的新篇章 近年來&#xff0c;大規模語言模型&#xff08;LLM&#xff09;在推理任務上的表現令人矚目&#xff0c;尤其是在數學競賽&#xff08;如AIME&#xff09;和編程任務中&#xff0c;強化學習&#xff08;RL&#xff09;成為…

【Qt】QWidget的styleSheet屬性

&#x1f3e0;個人主頁&#xff1a;Yui_ &#x1f351;操作環境&#xff1a;Qt Creator &#x1f680;所屬專欄&#xff1a;Qt 文章目錄 前言1. styleSheet屬性2. 利用styleSheet屬性實現簡單的日夜模式切換2.1 知識補充-計算機中的顏色表示 3. 總結 前言 style?好像前端的st…

QT Quick(C++)跨平臺應用程序項目實戰教程 2 — 環境搭建和項目創建

目錄 引言 1. 安裝Qt開發環境 1.1 下載Qt安裝包 1.2 安裝Qt 1.3 安裝MSVC編譯器 2. 創建Qt Quick項目 2.1 創建新項目 2.2 項目結構 2.3 運行項目 3. 理解項目代碼 3.1 main.cpp文件 3.2 Main.qml文件 引言 在上一篇文章中&#xff0c;我們介紹了本教程的目標和結…

macOS Sequoia 15.3 一直彈出“xx正在訪問你的屏幕”

&#x1f645; 問題描述 macOS 系統升級后&#xff08;15.2或者15.3均出現過此問題&#xff09;&#xff0c;不管是截圖還是開騰訊會議&#xff0c;只要跟捕捉屏幕有關&#xff0c;都一直彈出這個選項&#xff0c;而且所有軟件我都允許訪問屏幕了&#xff0c;這個不是詢問是否…

二叉樹的學習

目錄 樹型結構&#xff08;了解&#xff09; 概念 概念&#xff08;重要&#xff09; 樹的表示形式&#xff08;了解&#xff09; 樹的應用 二叉樹&#xff08;重點&#xff09; 概念 兩種特殊的二叉樹 二叉樹的性質 利用性質做題&#xff08;關鍵&#xff09; 二叉…

AbMole新生大鼠腦類器官培養Protocol

近日&#xff0c;希臘亞里士多德大學塞薩洛尼基分校的研究團隊在《神經科學方法》&#xff08;Journal of Neuroscience Methods&#xff09;期刊上發表了一項引人注目的研究&#xff0c;他們開發了一種基于新生大鼠腦組織的新型類器官培養協議&#xff0c;并展望其在阿爾茨海默…

物理環境與安全

物理安全的重要性 信息系統安全戰略的一個重要組成部分物理安全面臨問題 環境風險不確定性人類活動的不可預知性 典型的物理安全問題 自然災害環境因素設備安全、介質安全、傳輸安全 場地選擇 區域&#xff1a;避開自然災害高發區環境&#xff1a;原理可能的危險因素抗震&…

手動離線安裝NextCloud插件

1、下載離線插件安裝包 進入NextCloud官方插件商城&#xff1a;https://apps.nextcloud.com/ 選擇自己需要的插件軟件 選擇NextCloud對應版本的插件安裝包 2、解壓安裝 進入的到NextCloud安裝目錄的apps目錄 cd /var/www/html/apps 將下載的xxx.tar.gz復制到apps目錄中解…

算力100問?第93問:算力資源為何更分散了?

目錄 1、政策驅動與地方投資的盲目性 2、美國芯片斷供與國產替代的陣痛 3、政企市場對私有云的偏好 4、技術標準與供需結構的失衡 5、產業生態與市場機制的滯后 6、破局路徑與未來展望 在大模型和人工智能技術快速發展的背景下,算力資源已成為數字經濟時代的核心基礎設施…