Unity實(shí)現(xiàn)局域網(wǎng)聊天室功能
基于Unity實(shí)現(xiàn)一個(gè)簡(jiǎn)單的局域網(wǎng)聊天室,供大家參考,具體內(nèi)容如下
學(xué)習(xí)Unity有一點(diǎn)時(shí)間了,之前學(xué)的都是做客戶端的一些內(nèi)容,現(xiàn)在開(kāi)始學(xué)習(xí)聯(lián)網(wǎng)。我的這個(gè)是在觀看了 Siki 的教學(xué)內(nèi)容來(lái)做的,也有自己的一點(diǎn)點(diǎn)小小的改動(dòng)在里面。純粹用于練手了。
因?yàn)楸救艘彩切“滓幻?,所以,有錯(cuò)誤的地方或者更好的實(shí)現(xiàn)方法,也希望有大神能幫忙指正,多謝!
整體過(guò)程分為兩部分:構(gòu)建服務(wù)端、構(gòu)建客戶端。
服務(wù)端:
大概思路:
1. 聲明Socket連接以及綁定IP和端口,這里面使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace ServerApplication
{
class Program
{
public static string IP;
public static int Port;
static List<Client> clientList = new List<Client>();
static Socket serverSocket;
static void Main(string[] args)
{
//綁定IP和端口
BindIPAndPort();
//
while (true)
{
Socket clientSocket = serverSocket.Accept();
Client client = new Client(clientSocket);
clientList.Add(client);
Console.WriteLine("一臺(tái)主機(jī)進(jìn)入連接");
}
}
/// <summary>
/// 廣播數(shù)據(jù)
/// </summary>
public static void BroadcostMSG(string s)
{
List<Client> NotConnectedList = new List<Client>();
foreach (var item in clientList)
{
if(item.IsConnected)
{
item.SendMSG(s);
}
else
{
NotConnectedList.Add(item);
}
}
foreach (var item in NotConnectedList)
{
clientList.Remove(item);
}
}
/// <summary>
/// 綁定IP和端口
/// </summary>
public static void BindIPAndPort()
{
//創(chuàng)建一個(gè)serverSocket
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//聲明IP和端口
Console.WriteLine("輸入IP地址:");
IP = Console.ReadLine();
string ipStr = IP;
Console.WriteLine("請(qǐng)輸入端口:");
Port = int.Parse(Console.ReadLine());
int port = Port;
IPAddress serverIp = IPAddress.Parse(ipStr);
EndPoint serverPoint = new IPEndPoint(serverIp, port);
//socket和ip進(jìn)行綁定
serverSocket.Bind(serverPoint);
//監(jiān)聽(tīng)最大數(shù)為100
serverSocket.Listen(100);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Threading;
namespace ServerApplication
{
class Client
{
public Socket clientSocket;
//聲明一個(gè)線程用于接收信息
Thread t;
//接收信息所用容器
byte[] data = new byte[1024];
//構(gòu)造函數(shù)
public Client(Socket s)
{
clientSocket = s;
t = new Thread(ReceiveMSG);
t.Start();
}
/// <summary>
/// 接收數(shù)據(jù)
/// </summary>
void ReceiveMSG()
{
while(true)
{
if (clientSocket.Poll(10,SelectMode.SelectRead))
{
break;
}
data = new byte[1024];
int length = clientSocket.Receive(data);
string message = Encoding.UTF8.GetString(data, 0, length);
Program.BroadcostMSG(message);
Console.WriteLine("收到消息:" + message);
}
}
/// <summary>
/// 發(fā)送數(shù)據(jù)
/// </summary>
/// <param name="s"></param>
public void SendMSG(string message)
{
byte[] data = Encoding.UTF8.GetBytes(message);
clientSocket.Send(data);
}
//判斷此Client對(duì)象是否在連接狀態(tài)
public bool IsConnected
{
get { return clientSocket.Connected; }
}
}
}
客戶端:
a.UI界面
UI界面是使用UGUI實(shí)現(xiàn)的
登錄用戶可以自己取名進(jìn)行登錄(發(fā)言時(shí)用于顯示),使用時(shí)需要輸入服務(wù)端的IP地址和端口號(hào)

下面是聊天室的頁(yè)面,在輸入框內(nèi)輸入要發(fā)送的消息,點(diǎn)擊Send,將信息發(fā)送出去

這是服務(wù)端的信息

b.關(guān)于客戶端的腳本
(1)這是ClientManager,負(fù)責(zé)與服務(wù)端進(jìn)行連接,通信
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System.Net;
using System.Text;
using UnityEngine.UI;
using System.Threading;
public class ClientManager : MonoBehaviour
{
//ip:192.168.1.7
public string ipAddressstr;
public int port;
public Text ipTextToShow;
//Socket
private Socket ClientServer;
//文本輸入框
public InputField inputTxt;
public string inputMSGStr;
//接收
Thread t;
public Text receiveTextCom;
public string message;
// Use this for initialization
void Start()
{
ipTextToShow.text = ipAddressstr;
// ConnectedToServer();
}
// Update is called once per frame
void Update()
{
if (message != null && message != "")
{
receiveTextCom.text = receiveTextCom.text + "\n" + message;
message = "";
}
}
/// <summary>
/// 連接服務(wù)器
/// </summary>
public void ConnectedToServer()
{
ClientServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//聲明IP地址和端口
IPAddress ServerAddress = IPAddress.Parse(ipAddressstr);
EndPoint ServerPoint = new IPEndPoint(ServerAddress, port);
ipAddressstr = IpInfo.ipStr;
port = IpInfo.portStr;
//開(kāi)始連接
ClientServer.Connect(ServerPoint);
t = new Thread(ReceiveMSG);
t.Start();
}
/// <summary>
/// 接收消息
/// </summary>
/// <returns>“string”</returns>
void ReceiveMSG()
{
while (true)
{
if (ClientServer.Connected == false)
{
break;
}
byte[] data = new byte[1024];
int length = ClientServer.Receive(data);
message = Encoding.UTF8.GetString(data, 0, length);
//Debug.Log("有消息進(jìn)來(lái)");
}
}
/// <summary>
/// 發(fā)送string類(lèi)型數(shù)據(jù)
/// </summary>
/// <param name="input"></param>
public void SendMSG()
{
Debug.Log("button Clicked");
//message = "我:" + inputTxt.text;
inputMSGStr = inputTxt.text;
byte[] data = Encoding.UTF8.GetBytes(IpInfo.name+":"+inputMSGStr);
ClientServer.Send(data);
}
private void OnDestroy()
{
ClientServer.Shutdown(SocketShutdown.Both);
ClientServer.Close();
}
private void OnApplicationQuit()
{
OnDestroy();
}
}
(2)SceneManager,用于場(chǎng)景切換,這里只是利用GameObject進(jìn)行SetActive()來(lái)實(shí)現(xiàn),并不是創(chuàng)建了單獨(dú)的Scene進(jìn)行管理。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SceneManager : MonoBehaviour {
public GameObject loginPanel;
public GameObject communicatingPanel;
// Use this for initialization
public void OnSwitch()
{
loginPanel.SetActive(false);
communicatingPanel.SetActive(true);
}
}
(3)LogInPanel和IPInfo,一個(gè)掛載在登錄界面上,一個(gè)是數(shù)據(jù)模型,用于存儲(chǔ)數(shù)據(jù)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class LogInPanel : MonoBehaviour {
public Text nameInputTxt;
public Text ipInputTxt;
public Text portInputTxt;
//private string name;
//private string ipStr;
//private string portStr;
public void OnLogInClick()
{
IpInfo.name = nameInputTxt.text;
IpInfo.ipStr = ipInputTxt.text;
IpInfo.portStr = int.Parse(portInputTxt.text);
}
}
public static class IpInfo {
public static string name;
public static string ipStr;
public static int portStr;
}
總結(jié):第一次寫(xiě)學(xué)習(xí)博,還有很多地方要學(xué)習(xí)啊。
留待解決的問(wèn)題:此聊天室只能用于局域網(wǎng)以內(nèi),廣域網(wǎng)就無(wú)法實(shí)現(xiàn)通信了,還要看看怎么實(shí)現(xiàn)遠(yuǎn)程的一個(gè)通信,不然這個(gè)就沒(méi)有存在的意義了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#中List轉(zhuǎn)IList的實(shí)現(xiàn)
本文主要介紹了C#中List轉(zhuǎn)IList的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
winform樹(shù)形菜單無(wú)限級(jí)分類(lèi)實(shí)例
本文介紹了“winform樹(shù)形菜單無(wú)限級(jí)分類(lèi)實(shí)例”,需要的朋友可以參考一下2013-03-03
C#的正則表達(dá)式Regex類(lèi)使用簡(jiǎn)明教程
這篇文章主要介紹了C#的正則表達(dá)式Regex類(lèi)使用簡(jiǎn)明教程,分別講解了如何匹配、如何獲取匹配次數(shù)、如何獲取匹配內(nèi)容及捕獲的方法,需要的朋友可以參考下2014-08-08
常用.NET工具(包括.NET可再發(fā)行包2.0)下載
常用.NET工具(包括.NET可再發(fā)行包2.0)下載...2007-03-03
解析如何正確使用SqlConnection的實(shí)現(xiàn)方法
本篇文章對(duì)如何正確使用SqlConnection的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C#實(shí)現(xiàn)系統(tǒng)托盤(pán)通知的方法
這篇文章主要介紹了C#實(shí)現(xiàn)系統(tǒng)托盤(pán)通知的方法,涉及C#系統(tǒng)api調(diào)用的相關(guān)技巧,需要的朋友可以參考下2015-06-06
C#中使用Dapper進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)的流程步驟
在C#中,Dapper是一個(gè)非常流行的ORM(對(duì)象關(guān)系映射)工具,它提供了一個(gè)輕量級(jí)的方式來(lái)訪問(wèn)數(shù)據(jù)庫(kù),Dapper通過(guò)SQL語(yǔ)句與數(shù)據(jù)庫(kù)進(jìn)行交互,并將結(jié)果映射到.NET對(duì)象中,以下是如何在C#中使用Dapper進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)的基本步驟,需要的朋友可以參考下2024-12-12

