1. 程式人生 > 其它 >遊戲開發伺服器人們筆記2-簡易聊天室(非同步伺服器)

遊戲開發伺服器人們筆記2-簡易聊天室(非同步伺服器)

技術標籤:網路unity

客戶端:

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

public class Echo : MonoBehaviour {
    /// <summary>
    /// 定義套接字
    /// </summary>
    Socket F_socket;
    /// <summary>
    /// UI文字輸入
/// </summary> public InputField F_input; public Text F_text; /// <summary> /// 接收緩衝區 /// </summary> byte[] readBuff = new byte[1024]; string recvStr = ""; /// <summary> /// 連線網路 /// </summary> public void Collection() { //配置地址族、套接字型別、協議
//地址族:InterNetwork-IPv4,InterNetworkV6-IPv6 //套接字型別:通常使用Stream,Dgram、Raw、RDM、Seqpacket、Unknown //協議:通常使用TCP,GGP、ICMP、ICMPv6、IP、Internet、PARC、RAW、UDP、Unknown、Unspecified F_socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); //連線伺服器 F_socket.
BeginConnect("10.32.3.208",8888, ConnectCallback, F_socket); } /// <summary> /// connect回撥 /// </summary> /// <param name="ar"></param> public void ConnectCallback(IAsyncResult ar) { try { Socket socket = (Socket)ar.AsyncState; socket.EndConnect(ar); Debug.Log("Connection successful"); socket.BeginReceive(readBuff,0,1024,0, ReceiveCallback, F_socket); } catch(SocketException e) { Debug.Log("Socket Connect fail"+e.ToString()); } } /// <summary> /// receive回撥 /// </summary> public void ReceiveCallback(IAsyncResult ar) { try { Socket socket = (Socket)ar.AsyncState; int count = socket.EndReceive(ar); //將位元組流轉化為字串 recvStr = System.Text.Encoding.Default.GetString(readBuff, 0, count); socket.BeginReceive(readBuff, 0, 1024, 0, ReceiveCallback, F_socket); } catch(SocketException e) { Debug.Log("Socket Receiver fail"+e.ToString()); } } /// <summary> /// 傳送文字 /// </summary> public void Send() { //獲取傳送的文字 string sendStr = F_input.text; //文字轉換為byte串 byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr); //傳送位元組流 F_socket.BeginSend(sendBytes,0,sendBytes.Length,0,SendCallback,F_socket); } /// <summary> /// 回撥send /// </summary> /// <param name="ar"></param> public void SendCallback(IAsyncResult ar) { try { Socket socket = (Socket)ar.AsyncState; int count = socket.EndSend(ar); string s = System.Text.Encoding.Default.GetString(readBuff,0,count); recvStr = s + "\n" + recvStr; } catch (SocketException e) { Debug.Log("Socket send fail"+e.ToString()); } } private void Update() { //實時更新伺服器反饋訊息記錄 F_text.text = recvStr; } }

伺服器:

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;

namespace EchoServer
{
	//使用者狀態
	class ClientState{
		//套接字
		public Socket socket;
		//位元組流
		public byte[] readBuff=new byte[1024];
	}
	class MainClass
	{
		//監聽socket
		static Socket listenfd ;
		//客戶端socket及狀態資訊
		static Dictionary<Socket,ClientState>clients=new Dictionary<Socket, ClientState>();

		public static void Main (string[] args)
		{

			listenfd= new Socket (AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

			//設定套接字和IP埠,並進行繫結
			IPAddress ipAdr = IPAddress.Parse ("10.32.3.208");
			IPEndPoint ipEP = new IPEndPoint (ipAdr,8888);
			listenfd.Bind (ipEP);

			//開啟監聽,數字表示限制的連線數
			listenfd.Listen (0);
			Console.WriteLine ("伺服器啟動成功");

			listenfd.BeginAccept (AcceptCallback,listenfd);
			Console.ReadLine ();
		}
		//accept回撥
		public static void AcceptCallback(IAsyncResult ar){
			try{
				Console.WriteLine ("[伺服器]接收");
				Socket listenfd=(Socket)ar.AsyncState;
				Socket clientfd=listenfd.EndAccept(ar);

				ClientState state=new ClientState();
				state.socket=clientfd;
				clients.Add(clientfd,state);
				clientfd.BeginReceive(state.readBuff,0,1024,0,ReceiveCallback,state);
				listenfd.BeginAccept(AcceptCallback,listenfd);
			}
			catch(SocketException e){
				Console.WriteLine ("Socket Accept fail"+e.ToString());
			}
		}
		//receive回撥
		public static void ReceiveCallback(IAsyncResult ar){
			try{
				ClientState state=(ClientState)ar.AsyncState;
				Socket clientfd=state.socket;
				int count=clientfd.EndReceive(ar);
				//客戶端為0
				if(count==0){
					clientfd.Close();
					clients.Remove(clientfd);
					Console.WriteLine ("Socket Close");
					return;
				}
				string recvStr=System.Text.Encoding.Default.GetString(state.readBuff,0,count);
				byte[] sendBytes=System.Text.Encoding.Default.GetBytes("mode in LFF:\n"+recvStr);
				//廣播
				foreach(ClientState s in clients.Values){
					s.socket.Send(sendBytes);
				}
				clientfd.BeginReceive(state.readBuff,0,1024,0,ReceiveCallback,state);
			}
			catch(SocketException e){
				Console.WriteLine ("Socket Receive fail"+e.ToString());
			}
		}
	}
}