基于Unity下的Socket-套接字實現簡單的本地局域網聊天功能

我們知道 除了單機游戲 其他所有游戲都是需要網絡通信的 跟其他用戶去交互 最近跟著大神老師學習了Socket 接下來 就和大家分享一下 如何用Socket實現簡單的本地聊天功能(這只是Socket入門的小玩意讓你理解了解一下 如果真正用到Socket 這個demo實在是拿不出手)

首先給大家看下效果:

Jietu20170601-211457.jpg

下面介紹腳本 一共有四個腳本

有序列表

1.SocketFrameworkUse腳本 (見圖1 掛在Control上 它是一個空物體 下放了圖上的ui控件)
2.SocketFramework腳本 核心腳本(支撐腳本 無須掛在游戲對象上)
3.ServerControl腳本(見圖2 2.1 掛在ServerControl上 它是一個空物體 下放了圖上的ui控件)
4.PortControl腳本(見圖3 3.1 掛在PortControl上 它是一個空物體 下放了圖上的ui控件)

  1. 圖3 和圖2 不一樣 一個是客服端的發送界面 一個是接收端界面


    4.jpg

圖1

Jietu20170601-212159.jpg

圖2 2.1

2.jpg
1.jpg

圖3 3.1

7.jpg
0.jpg

下面是各個腳本代碼 注意 public GameObject對象全部是從面板拖進去的 沒有用代碼找到該對象

引用1.SocketFramework腳本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System.Net;
using System.Net.Sockets;
using System.Text;

/// <summary>
/// 消息回調
/// </summary>
public delegate void SocketCallback(string msg);

public class SocketFramework {

private static SocketFramework ins;

public static SocketFramework GetIns ()
{
    if (ins == null) 
    {
        ins = new SocketFramework ();
    }

    return ins;
}

private SocketFramework(){}

#region 服務器端

//聲明一個服務器套接字
private Socket serverSocket;
//服務器回調
private SocketCallback serverCallback;
//服務器消息緩存
private byte[] serverBuffer;
//已連接的Socket
private Socket m_workingSocket;

public void ServerInit(SocketCallback cb)
{
    //定義Buffer長度
    serverBuffer = new byte[100];
    //接收回調
    serverCallback = cb;
    //1、初始化Socket
    serverSocket = new Socket (AddressFamily.InterNetwork/*地址族:IPV4*/,
        SocketType.Stream/*雙向讀寫流*/, ProtocolType.Tcp/*傳輸層使用協議*/);
    //定義一個網絡節點
    IPEndPoint ep = new IPEndPoint(IPAddress.Any/*選擇已經連接到互聯網的最優的網絡地址*/,23456);
    //2、綁定網絡節點
    serverSocket.Bind (ep);
    //3、設置異步監聽數量
    serverSocket.Listen(20);
    //向上層發送服務器創建成功的消息
    serverCallback("Server Has Init!!!" );
    //4、異步接受客戶端的連接請求
    serverSocket.BeginAccept(ServerAcceptCallback,serverSocket);
}

/// <summary>
/// 異步接受消息的回調
/// </summary>
/// <param name="ar">Ar.</param>
private void ServerAcceptCallback(System.IAsyncResult ar)
{
    //獲取當前的套接字
    Socket currentSocket = ar.AsyncState as Socket;
    //結束接受請求
    m_workingSocket = currentSocket.EndAccept (ar);
    ////向上層發送接受到客戶端的消息
    serverCallback("Accept Client:" + m_workingSocket.LocalEndPoint);
    //5、開啟異步接收客戶端的消息
    m_workingSocket.BeginReceive (serverBuffer/*消息緩存*/, 0/*消息起始點*/,serverBuffer.Length/*消息長度*/
        , SocketFlags.None/*消息標志位*/, ServerReceiveCallback/*消息回調*/, m_workingSocket);
    //尾遞歸
    //4、異步接受客戶端的連接請求
    serverSocket.BeginAccept(ServerAcceptCallback,serverSocket);
}

/// <summary>
/// 異步接收消息的回調
/// </summary>
/// <param name="ar">Ar.</param>
private void ServerReceiveCallback(System.IAsyncResult ar)
{
    //接收套接字
    Socket workingSocket = ar.AsyncState as Socket;
    //結束接收消息
    int count = workingSocket.EndReceive (ar);
    //將消息取出
    string currentMsg = UTF8Encoding.UTF8.GetString(serverBuffer);
    //清空緩存
    serverBuffer = new byte[100];
    //將接收到的消息傳到上層
    serverCallback ("ReveiveMsg From " + workingSocket.LocalEndPoint + " Data:" + currentMsg);
    //尾遞歸
    //5、開啟異步接收客戶端的消息
    workingSocket.BeginReceive (serverBuffer/*消息緩存*/, 0/*消息起始點*/,serverBuffer.Length/*消息長度*/,
        SocketFlags.None/*消息標志位*/, ServerReceiveCallback/*消息回調*/, workingSocket);
}
/// <summary>
/// 服務器發送消息方法
/// </summary>
/// <param name="msg">Message.</param>
public void ServerSend(string msg)
{
    //將要發送的消息轉成比特流
    serverBuffer = UTF8Encoding.UTF8.GetBytes (msg);
    //異步發送
    m_workingSocket.BeginSend (serverBuffer, 0, serverBuffer.Length, SocketFlags.None, ServerSendCallback, m_workingSocket);
    //將發送消息的信息發送上層
    serverCallback("Server Send Msg : " + msg);
}

/// <summary>
/// 服務器異步發送的回調
/// </summary>
/// <param name="ar">Ar.</param>
private void ServerSendCallback(System.IAsyncResult ar)
{
    Socket workingSocket = ar.AsyncState as Socket;
    //服務器結束發送消息
    int count = workingSocket.EndSend (ar);
}

#endregion

#region 客戶端

//客戶端套接字
private Socket clientSocket;
//客戶端回調
private SocketCallback clientCallback;
//客戶端緩存
private byte[] clientBuffer;

public void ClientConnect(string serverIp,int serverPort, SocketCallback cb)
{
    //注冊客戶端回調
    clientCallback = cb;
    //初始化緩存
    clientBuffer = new byte[100];
    //1、初始化客戶端Socket
    clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
    //2、連接服務器
    clientSocket.BeginConnect (new IPEndPoint (IPAddress.Parse (serverIp), serverPort)/*服務器的網絡節點*/, 
        ClientConnectCallback, clientSocket);

}
/// <summary>
/// 客戶端連接的回調
/// </summary>
/// <param name="ar">Ar.</param>
private void ClientConnectCallback(System.IAsyncResult ar)
{
    //連接好的套接字
    Socket connectSocket = ar.AsyncState as Socket;
    //向上層發送連接成功的消息
    clientCallback ("Has Connect To Server : " + connectSocket.LocalEndPoint);
    //結束連接
    connectSocket.EndConnect (ar);
    //3、開啟異步接收消息
    connectSocket.BeginReceive(clientBuffer,0,clientBuffer.Length,SocketFlags.None,ClientReceiveCallback,connectSocket);
}
/// <summary>
/// 客戶端異步接收消息的回調
/// </summary>
/// <param name="ar">Ar.</param>
private void ClientReceiveCallback(System.IAsyncResult ar)
{
    Socket workingSocket = ar.AsyncState as Socket;
    //接收完畢
    int count = workingSocket.EndReceive (ar);
    //取出消息
    string data = UTF8Encoding.UTF8.GetString(clientBuffer);
    //接收到消息
    clientCallback ("ReceiveMsg : " + data);
    //清空
    clientBuffer = new byte[100];
    //尾遞歸
    //3、開啟異步接收消息
    workingSocket.BeginReceive(clientBuffer,0,clientBuffer.Length,SocketFlags.None,ClientReceiveCallback,workingSocket);
}

/// <summary>
/// 客戶端發送方法
/// </summary>
/// <param name="msg">Message.</param>
public void ClientSend(string msg)
{
    //將字符串轉成比特流
    clientBuffer = UTF8Encoding.UTF8.GetBytes (msg);
    //4、異步發送
    clientSocket.BeginSend (clientBuffer, 0, clientBuffer.Length, SocketFlags.None, ClientSendCallback, clientSocket);
}
/// <summary>
/// 客戶端發送回調
/// </summary>
/// <param name="ar">Ar.</param>
private void ClientSendCallback(System.IAsyncResult ar)
{
    Socket workingSocket = ar.AsyncState as Socket;
    //結束發送
    workingSocket.EndSend (ar);
}
#endregion

}

引用2.SocketFrameworkUse腳本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI ;
using UnityEngine.SceneManagement ;
public class SocketFrameworkUse : MonoBehaviour {

public static SocketFrameworkUse Instant;


public InputField ipField;
public InputField portField;

public GameObject ServerControl ;
public GameObject PortControl;
//網絡狀態(0表示未連接,1表示服務器,2表示客戶端)
int networkState = 0;

#region UI變量

string clientConnectIP = "10.0.158.88" ;
string clientConnectPort = "23456" ;
string msgText = "" ;
public string currentMsg="" ;

#endregion

void Awake()
{
    Instant = this;

}

void Start()
{
    Application.runInBackground = true ;
}

void MsgCallback(string msg)
{
    currentMsg += msg + "\n" ;
}


// 我是服務端調按鈕回調

public void ServerBnt()
{
    
           // 初始化服務器
        SocketFramework.GetIns().ServerInit(MsgCallback);
        
        // 跳到服務端界面
    
    ServerControl.SetActive (true);
    gameObject.SetActive (false);


}

// 我是接收端按鈕回調方法
public void PortBtn()
{
    clientConnectIP = ipField.text;
    clientConnectPort = portField.text;
    SocketFramework.GetIns ().ClientConnect (clientConnectIP,
        int.Parse (clientConnectPort), MsgCallback);
    
    PortControl.SetActive (true);
    gameObject.SetActive (false);
}

}

引用3.ServerControl腳本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI ;

public class ServerControl : MonoBehaviour {

public InputField sendField;

void Awake()
{
    gameObject.SetActive (false);

}

// Use this for initialization
void Start () {
    
}

// Update is called once per frame
void Update () {
    
}


// 服務端發送消息按鈕回調
public void SendMessage()
{
    string msgText = sendField.text;
    SocketFramework.GetIns ().ServerSend (msgText);

}

void OnGUI()
{
    //顯示所有消息
    GUILayout.Label (SocketFrameworkUse.Instant.currentMsg);

}

}

引用4.PortControl腳本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI ;
public class PortControl : MonoBehaviour {

public InputField sendField;


void Awake()
{

    gameObject.SetActive (false);
}
// Use this for initialization
void Start () {
    
}

// Update is called once per frame
void Update () {
    
}

// 接收端發送消息按鈕回調
public void SendMessage()
{
    string msgText = sendField.text;
    SocketFramework.GetIns ().ClientSend (msgText);

}

void OnGUI()
{
    //顯示所有消息
    GUILayout.Label ( SocketFrameworkUse.Instant.currentMsg);

}

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,250評論 6 530
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,923評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,041評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,475評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,253評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,801評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,882評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,023評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,530評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,494評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,639評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,177評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,890評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,289評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,552評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,242評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,626評論 2 370

推薦閱讀更多精彩內容