Jtro的技術分享:游戲客戶端與服務器(c#)通訊_同步Socket
小編:啊南 45閱讀 2020.11.17
在游戲界,獨立游戲層出不窮,但是大部分都是單機,網絡游戲很少,因為不會有獨立開發者自己整一個服務器,除非你先去買個虛擬服務器。網絡通訊一直是一個很大的學術,
廢話不多說,直接上代碼,首先是服務器端的,這個不需要打開unity,直接打開mono或者是vs直接輸入代碼在控制臺運行就行
``` using System; using System.Net; //引入命名空間 using System.Net.Sockets; //引入命名空間 using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Server { class Program { static void Main(string[] args) { Console.WriteLine("這是一個服務器,你相信嗎?"); //Socket 套接字 Socket listenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); /* * 現在解釋上面的一行代碼,功能是實例了一個套接字,它的3個參數分別代表了地址簇、套接字類型和協議 * 地址簇指明用的是IPv4還是用的是IPv6, * SocketType指的是套接字的類型,游戲開發中用的stream居多 * ProtocolType指明使用的協議,如你所見,用的是TCP協議 */ //Bind IPAddress ipAdr = IPAddress.Parse("127.0.0.1"); IPEndPoint ipEp = new IPEndPoint(ipAdr ,1234); listenfd.Bind(ipEp); /* * listenfd.Bind(ipEp)將給listenfd套接字綁定IP和端口。在這里是綁定的是本地地址127.0.0.1和1234號端口 * 127.0.0.1是回送地址,指的是本地機,一般用來測試,當然你可以設置成另外一臺機的ip地址,然后在2臺電 * 腦上分別運行客戶端和服務器端 */ //Listen listenfd.Listen(0); Console.WriteLine("[ 服務器 ] 啟動成功"); /* * listenfd.Listen(0)開啟監聽器,等待客戶端連接,參數backlog指定隊列中最多可容納多少人連接,0表示不限制 */ while (true) { //Accept Socket connfd = listenfd.Accept(); Console.WriteLine("[服務器] Accept"); /* * 開啟監聽器后,服務器開始調用listenfd.Accept()接收客戶端連接。本案例使用的所有Socket方法都是“阻塞” * 方法,也就是說,如果一直沒有客戶點連接進來的話,服務器的程序會一直卡在listenfd.Accpect()處,不往 * 下執行,直到客戶端連接之后Accpet返回一個新的客戶端的Socket,對于服務器來說它有一個監聽的Socket(案 * 例中的listenfd)用來接收Accpet客戶端的連接,對于每一個客戶端來說,還有一個專門的Socket(案例中的Connfd) * 用來處理該客戶端的數據 */ //Recv byte[] readBuff = new byte[1024]; int count = connfd.Receive(readBuff); string str = System.Text.Encoding.UTF8.GetString(readBuff, 0, count); Console.WriteLine("[ 服務器接收 ]" +str); /* * 服務器通過connfd.Receive接收客戶端數據,receive也是阻塞的方法,沒有接收到客戶端數據時,程序卡在Receive * 處,不會向下執行,Receive帶有一個byte[]類型的參數,它將儲存接收到的數據,Receive的返回值則指明接收到的 * 數據長度之后,用string str = System.Text.Encoding.UTF8.GetString(readBuff, 0, count);這段代碼將byte[]數 * 組轉化為字符串顯示在屏幕上 */ //Send byte[] bytes = System.Text.Encoding.Default.GetBytes(" Serv echo " + str); connfd.Send(bytes); /* * 服務器通過Connfd.Send發送數據,它接收一個byte[]類型的參數指明要發送的內容,Send的返回值指明發送的數據長 * 度(案例中沒有),服務器程序用System.Text.Encoding.Default.GetBytes(" Serv echo " + str)把字符串轉換成 * byte[]數組,然后發送給客戶端。 */ } } } } ```
注釋已經寫的很明白了。
這是運行的圖:

服務器運行的 時候 客戶端還沒鏈接
那么接下來就是unity客戶端的了
首先新建一個unity空工程,我的unity版本是2017.2.0.f3的版本,所以2017.2.0.f3版本之下的版本復制粘貼都沒問題。
新建畫布添加組件,和我這個差不多就行。排版自己排就行。

組件 H ierarchy 視圖

Game 視圖
新建一個腳本,叫NET,這里同樣貼出代碼,方便大家復制粘貼調試。
``` using System.Collections; using System.Collections.Generic;using UnityEngine;using System.Net; //引入命名空間 using System.Net.Sockets; //引入命名空間 using UnityEngine.UI;public class net : MonoBehaviour { Socket socket; //與服務器端的套接字 public InputField HostInput; //服務器端的ip地址 public InputField PortInput; //服務器端的端口,其實在服務器那塊7777端口也能用。 public Text RecvText; //服務器收到的信息 public Text ClientText; //客戶端的信息 const int BUFFER_SIZE = 1024; //接收緩沖區 byte[] readBuff = new byte[BUFFER_SIZE]; ////// 按鈕點擊事件 ///public void Btn_Connetion() { //Socket socket = new Socket(AddressFamily .InterNetwork,SocketType.Stream ,ProtocolType.Tcp); //Connect string host = HostInput.text; string strport = PortInput.text; int port = int .Parse(strport); socket.Connect(host ,port); ClientText.text = "客戶端地址 " + socket.LocalEndPoint.ToString(); //Send string str = "HELLO , I am Jtro."; string time = System.DateTime.Now.ToString(); byte[] bytes = System.Text.Encoding.Default.GetBytes(str+ " "+time); socket.Send(bytes); //Recv int count = socket.Receive(readBuff); str = System.Text.Encoding.UTF8.GetString(readBuff, 0, count); RecvText.text = str; //Close socket.Close(); } // Use this for initialization void Start () {} // Update is called once per framevoid Update () { } } ```
然后運行時的截圖

輸入 服務器地址 點擊連接服務器
好了這樣就行了,可以看到發送的信息
相關推薦
- unity5.x C# 獲取屏幕寬度 設置不受重力影響 在unity5.x中,獲取屏幕寬度代碼如下:float screenWeight = Screen.width; //獲取屏幕寬度Screen.width 在此獲取屏幕的寬度,從而賦值給screenWeight變量。在unity5.x中在inspector中可以設置是否當前游戲對象是否受重力影響,那么選項如下:其中紅色標…
- Java向Oracle數據庫表中插入CLOB、BLOB字段 在需要存儲較長字符串到數據庫中時往往需要使用一些特殊類型的字段,在Oracle中即blob和clob字段,一般而言:Clob字段存儲字符信息,比如較長的文字、評論,Blob字段存儲字節信息,比如圖像的base64編碼。注意,上述字段的使用均可以用其他方式替代,比如用Mon…