您的位置:首页 > 移动开发 > Unity3D

Unity轻轻轻轻轻量级多人在线聊天系统

2017-09-05 23:52 183 查看
本篇文章使用C# socket tcp协议编写  用C#控制台建立服务器 监听一个连接池 将任意客户端发送的信息通过服务器发送至每个正在与服务器连接的客户端

这个参考unity网络编程实战第六章连接池的思路  明确异步接收的所有参数 用布尔变量循环检测连接池是否有位置

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace unityServer
{
class Conn
{
public const int BUFFER_SIZE = 1024;
public int bufCount = 0;
public byte[] readBuf = new byte[BUFFER_SIZE];
public bool isUse=false;
public Socket socket;
public Conn() {
readBuf = new byte[BUFFER_SIZE];
}
public void Init(Socket client) {
socket = client;
isUse = true;
}
public string GetAdress() {
if (!isUse)
return "无法获取地址";
return socket.RemoteEndPoint.ToString();
}
public int BufRemain() {
return BUFFER_SIZE - bufCount;
}
public void Close() {
if (!isUse)
return;
Console.WriteLine("断开连接"+GetAdress());
socket.Close();
isUse = false;
}
}
}
极简易的服务器  还是用异步+递归无限 检测客户端的和数据的传入
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace unityServer
{
class Serv
{
public Conn[] conns;
public Socket listenFd;
public int maxConn = 50;

public int NewIndex() {
if (conns == null)
return -1;
for(int i=0;i<conns.Length;i++){
if (conns[i] == null){
conns[i] = new Conn();
return i;
}
else if (conns[i].isUse==false)
return i;
}
return -1;
}
public void Start() {
conns = new Conn[maxConn];
for (int i = 0; i < maxConn; i++)
conns[i] = new Conn();

listenFd = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
listenFd.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"),8000));
listenFd.Listen(maxConn);
asyncAccept(listenFd);
Console.WriteLine("[服务器]已开启");
}

public void asyncAccept(Socket Ser){
try
{
Ser.BeginAccept(asyncResult =>
{
Socket tcpClient = Ser.EndAccept(asyncResult);
int Index = NewIndex();
if (Index < 0)
{
tcpClient.Close();
Console.WriteLine("[警告]连接满了");
}
else
{
Conn Client = conns[Index];
Client.Init(tcpClient);
Console.WriteLine("客户端" + Client.GetAdress() + "conns池:" + Index);
asyncRecive(Client);
}
asyncAccept(Ser);

}, null);

}
catch(Exception ex) {
Console.WriteLine(ex.Message);
}

}
public void asyncRecive(Conn tcpClient) {
try{
tcpClient.socket.BeginReceive(tcpClient.readBuf, tcpClient.bufCount, tcpClient.BufRemain(), SocketFlags.None, asyncResult =>{
int count = tcpClient.socket.EndReceive(asyncResult);
if (count < 0){
Console.WriteLine("[客户端]" + tcpClient.GetAdress() + "断开连接");
tcpClient.Close();
return;
}

string message = "[客户端]" + tcpClient.GetAdress() + "向您发送" + Encoding.UTF8.GetString(tcpClient.readBuf);

4000
Console.WriteLine(message);
byte[] data = Encoding.UTF8.GetBytes(message);
for (int i = 0; i < conns.Length; i++) {
if (conns[i] == null)
continue;
if (!conns[i].isUse)
continue;
tcpClient.socket.Send(data);
}
asyncRecive(tcpClient);
}, null);
}
catch(Exception ex){
Console.WriteLine(tcpClient.GetAdress()+"断开连接");
}

}
}
}
走起
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace unityServer
{
class Program
{
static void Main(string[] args)
{
Serv ser = new Serv();
ser.Start();
Console.Read();
}
}
}


接下来是客户端  在unity中拖拖拽拽弄个Text button InputFiled对号入座
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using UnityEngine.UI;
using System.Net;
using System.Net.Sockets;
public class ConnectToServer : MonoBehaviour {

public Text T_1,T_2;
public InputField ServerIP,Port,SendText;
public byte[] data=new byte[1024];
public Socket Client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
public void ConnectServ() {

Client.Connect(new IPEndPoint(IPAddress.Parse(ServerIP.text),int.Parse(Port.text)));
T_1.text = Client.LocalEndPoint.ToString();
asyncRecive(Client);
}
public void asyncRecive(Socket Client) {
Client.BeginReceive(data, 0, data.Length, SocketFlags.None, asyncResult =>
{
int length = Client.EndReceive(asyncResult);
string message = Encoding.UTF8.GetString(data);
T_2.text += message;
if (T_2.text.Length > 300) T_2.text = "";
asyncRecive(Client);
}, null);
}
// Update is called once per frame
public void SendMessage(){
byte[] data1 = Encoding.UTF8.GetBytes(SendText.text);
Client.Send(data1);

}
}
大概就是这个效果  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: