基于Unity下的Socket-套接字實(shí)現(xiàn)簡(jiǎn)單的本地局域網(wǎng)聊天功能

我們知道 除了單機(jī)游戲 其他所有游戲都是需要網(wǎng)絡(luò)通信的 跟其他用戶(hù)去交互 最近跟著大神老師學(xué)習(xí)了Socket 接下來(lái) 就和大家分享一下 如何用Socket實(shí)現(xiàn)簡(jiǎn)單的本地聊天功能(這只是Socket入門(mén)的小玩意讓你理解了解一下 如果真正用到Socket 這個(gè)demo實(shí)在是拿不出手)

首先給大家看下效果:

Jietu20170601-211457.jpg

下面介紹腳本 一共有四個(gè)腳本

有序列表

1.SocketFrameworkUse腳本 (見(jiàn)圖1 掛在Control上 它是一個(gè)空物體 下放了圖上的ui控件)
2.SocketFramework腳本 核心腳本(支撐腳本 無(wú)須掛在游戲?qū)ο笊希?br> 3.ServerControl腳本(見(jiàn)圖2 2.1 掛在ServerControl上 它是一個(gè)空物體 下放了圖上的ui控件)
4.PortControl腳本(見(jiàn)圖3 3.1 掛在PortControl上 它是一個(gè)空物體 下放了圖上的ui控件)

  1. 圖3 和圖2 不一樣 一個(gè)是客服端的發(fā)送界面 一個(gè)是接收端界面


    4.jpg

圖1

Jietu20170601-212159.jpg

圖2 2.1

2.jpg
1.jpg

圖3 3.1

7.jpg
0.jpg

下面是各個(gè)腳本代碼 注意 public GameObject對(duì)象全部是從面板拖進(jìn)去的 沒(méi)有用代碼找到該對(duì)象

引用1.SocketFramework腳本

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

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

/// <summary>
/// 消息回調(diào)
/// </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 服務(wù)器端

//聲明一個(gè)服務(wù)器套接字
private Socket serverSocket;
//服務(wù)器回調(diào)
private SocketCallback serverCallback;
//服務(wù)器消息緩存
private byte[] serverBuffer;
//已連接的Socket
private Socket m_workingSocket;

public void ServerInit(SocketCallback cb)
{
    //定義Buffer長(zhǎng)度
    serverBuffer = new byte[100];
    //接收回調(diào)
    serverCallback = cb;
    //1、初始化Socket
    serverSocket = new Socket (AddressFamily.InterNetwork/*地址族:IPV4*/,
        SocketType.Stream/*雙向讀寫(xiě)流*/, ProtocolType.Tcp/*傳輸層使用協(xié)議*/);
    //定義一個(gè)網(wǎng)絡(luò)節(jié)點(diǎn)
    IPEndPoint ep = new IPEndPoint(IPAddress.Any/*選擇已經(jīng)連接到互聯(lián)網(wǎng)的最優(yōu)的網(wǎng)絡(luò)地址*/,23456);
    //2、綁定網(wǎng)絡(luò)節(jié)點(diǎn)
    serverSocket.Bind (ep);
    //3、設(shè)置異步監(jiān)聽(tīng)數(shù)量
    serverSocket.Listen(20);
    //向上層發(fā)送服務(wù)器創(chuàng)建成功的消息
    serverCallback("Server Has Init?。?!" );
    //4、異步接受客戶(hù)端的連接請(qǐng)求
    serverSocket.BeginAccept(ServerAcceptCallback,serverSocket);
}

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

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

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

#endregion

#region 客戶(hù)端

//客戶(hù)端套接字
private Socket clientSocket;
//客戶(hù)端回調(diào)
private SocketCallback clientCallback;
//客戶(hù)端緩存
private byte[] clientBuffer;

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

}
/// <summary>
/// 客戶(hù)端連接的回調(diào)
/// </summary>
/// <param name="ar">Ar.</param>
private void ClientConnectCallback(System.IAsyncResult ar)
{
    //連接好的套接字
    Socket connectSocket = ar.AsyncState as Socket;
    //向上層發(fā)送連接成功的消息
    clientCallback ("Has Connect To Server : " + connectSocket.LocalEndPoint);
    //結(jié)束連接
    connectSocket.EndConnect (ar);
    //3、開(kāi)啟異步接收消息
    connectSocket.BeginReceive(clientBuffer,0,clientBuffer.Length,SocketFlags.None,ClientReceiveCallback,connectSocket);
}
/// <summary>
/// 客戶(hù)端異步接收消息的回調(diào)
/// </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、開(kāi)啟異步接收消息
    workingSocket.BeginReceive(clientBuffer,0,clientBuffer.Length,SocketFlags.None,ClientReceiveCallback,workingSocket);
}

/// <summary>
/// 客戶(hù)端發(fā)送方法
/// </summary>
/// <param name="msg">Message.</param>
public void ClientSend(string msg)
{
    //將字符串轉(zhuǎn)成比特流
    clientBuffer = UTF8Encoding.UTF8.GetBytes (msg);
    //4、異步發(fā)送
    clientSocket.BeginSend (clientBuffer, 0, clientBuffer.Length, SocketFlags.None, ClientSendCallback, clientSocket);
}
/// <summary>
/// 客戶(hù)端發(fā)送回調(diào)
/// </summary>
/// <param name="ar">Ar.</param>
private void ClientSendCallback(System.IAsyncResult ar)
{
    Socket workingSocket = ar.AsyncState as Socket;
    //結(jié)束發(fā)送
    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;
//網(wǎng)絡(luò)狀態(tài)(0表示未連接,1表示服務(wù)器,2表示客戶(hù)端)
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" ;
}


// 我是服務(wù)端調(diào)按鈕回調(diào)

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


}

// 我是接收端按鈕回調(diào)方法
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 () {
    
}


// 服務(wù)端發(fā)送消息按鈕回調(diào)
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 () {
    
}

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

}

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

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容