服务器端:在VS中新建项目,用于服务器的搭建
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
namespace Chat_Server
{
class Client
{
private Socket clientSocket;
private Thread t;
private byte[] data = new byte[1024];//接收数据容器
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.43.231"), 7788));
tcpServer.Listen(100);
Console.WriteLine("server is runing");
//死循环:解决只能接收一个客户端的问题
while (true)
{
Socket clientSocket = tcpServer.Accept();//暂停,当有客户端连接时执行下面代码
Console.WriteLine("有一个客户端连接上了");
Client client = new Client(clientSocket);
clientList.Add(client);
}
}
//是否连接成功,true为成功
public bool Connected
{
get { return clientSocket.Connected; }
}
public Client(Socket s)
{
clientSocket = s;
//启动一个线程 处理客户端的数据接收
t = new Thread(ReceiveMessage);
t.Start();
}
//接收从客户端发送的消息
private void ReceiveMessage()
{
//一直接收客户端的数据
while (true)
{
//在接收数据之前 判断一下socket连接是否断开,等待10毫秒响应。断开连接时:
if (clientSocket.Poll(10, SelectMode.SelectRead))
{
clientSocket.Close();
break;//跳出循环 终止线程的执行
}
//接收消息
int length = clientSocket.Receive(data);
string message = Encoding.UTF8.GetString(data, 0, length);
BroadcastMessage(message);
Console.WriteLine("收到了消息:" + message);
}
}
//服务器向客户端发消息
public void SendMessage(string message)
{
byte[] data = Encoding.UTF8.GetBytes(message);
clientSocket.Send(data);
}
//服务器端向客户端广播消息
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);
}
}
}
}
Unity客户端:
using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class ChatManager : MonoBehaviour
{
public string ipaddress = "192.168.43.231";
public int port = 7788;
public UIInput textInput;
public UILabel chatLabel;
private Socket clientSocket;
private Thread t;
private byte[] data = new byte[1024];//数据容器
private string message = "";//接收到的消息容器
void Start () {
ConnectToServer();
}
void Update () {
if (message != null && message != "")
{
chatLabel.text += "
" + message;
message = "";//清空消息
}
}
void ConnectToServer()
{
clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
//跟服务器端建立连接
clientSocket.Connect( new IPEndPoint(IPAddress.Parse(ipaddress),port) );
//创建一个新的线程 用来接收消息
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);
}
}
//发消息
void SendMessage(string message)
{
byte[] data = Encoding.UTF8.GetBytes(message);
clientSocket.Send(data);
}
//发送按钮
public void OnSendButtonClick()
{
string value = textInput.value;
SendMessage(value);
textInput.value = "";
}
void OnDestroy()
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();//关闭连接
}
}
注意:我们在客户端和服务器端都使用了线程,线程的作用在于加快出库速度,提高性能。服务器端,使用线程接收数据,客户端使用线程发送数据。