使用unity通過tcp建立聊天室
阿新 • • 發佈:2018-12-06
1.伺服器端建立
使用while迴圈不斷地接收客戶端的請求,將連線儲存到clientList中
class Program { static List<Client> clientList = new List<Client>(); static void Main(string[] args) { Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.103"),7788)); tcpServer.Listen(100); Console.WriteLine("server Running.."); while (true) { Console.WriteLine ("new Client Connected"); Socket clientSocket = tcpServer.Accept(); Client client = new Client(clientSocket);//把每個與客戶端通訊的邏輯放到Client類裡面進行處理 clientList.Add(client); } } }
使用Client類來處理與客戶端通訊的邏輯
class Client
{
private Socket clientSocket;
public Client(Socket s)
{
clientSocket = s;
}
}
2.客戶端的建立
講這個指令碼放在一個空物體上,客戶端連線伺服器,建立點選事件,再點選的時候獲取輸入框中的文字,傳送給伺服器
public class ChatManager : MonoBehaviour { public string ipaddress = "192.168.1.103"; public int port = 7788; public InputField inputField; private Socket clientSocket; void Start () { ConnectToServer(); } void Update () { } void ConnectToServer() { clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress), port)); Debug.Log("send connect"); } void SendMessage(string message) { byte[] data = Encoding.UTF8.GetBytes(message); clientSocket.Send(data); } public void OnSendButtonClick() { string value = inputField.text; SendMessage(value); } }
3.客戶端斷開
在客戶端斷開的時候斷開連線
void OnDestroy()
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();//關閉連線
}
在伺服器端
使用Poll方法(第一個引數是時間(ms),
模式(SelectMode) |
返回(return) |
SelectRead |
1. 如果已呼叫Listen並且有掛起的連線,則為true。 2.如果有資料可供讀取,則為true。 3.如果連線已關閉、重置或終止,則返回true。 |
SelectWrite |
1. 如果正在處理Connect並且連線已成功,則為true。 2. 如果可以傳送資料,則返回true。 |
SelectError |
1. 如果正在處理不阻止的Connect,並且連線已失敗,則為true。 2. 如果OutOfBandInline未設定,並且帶外資料可用,則為true。 |
)
if (clientSocket.Poll(10, SelectMode.SelectRead))
{
Console.WriteLine("連線中斷");
break;//終止執行緒執行
}
4.在伺服器端將資訊分發(廣播)到客戶端
在伺服器端接到訊息的時候呼叫廣播訊息的方法,將訊息進行廣播。使用靜態方法,在廣播的時候,遍歷列表中的連線列表中的全部。並將斷開連線的socket從列表中刪除
Program.BroadcastMessage(message);
public static void BroadcastMessage(string message)
{
var NotConnectedList = new List<Client>();
foreach(var client in clientList)
{
if (client.Connected)
{
client.SendMessage(message);
}
else
{
NotConnectedList.Add(client);
}
}
foreach(var temp in NotConnectedList)
{
clientList.Remove(temp);
}
}
在客戶端開啟一個執行緒接收來自伺服器端的訊息,在接收訊息的執行緒中,迴圈的接收訊息。
void ConnectToServer()
{
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress), port));
Debug.Log("send connect");
t = new Thread(ReceiveMessage);
t.Start();
}
void ReceiveMessage()
{
while (true)
{
if(clientSocket.Connected == false)
{
break;
}
int length = clientSocket.Receive(data);
message = Encoding.UTF8.GetString(data, 0, length);
}
}
在Update中監聽message,如果得到了伺服器傳送過來的訊息,就更新UI中的Text。
void Update () {
if(message != ""&& message!=null)
{
mtext.text += "\n" + message;
message = "";
}
}