经过几个小时的奋斗,终于把这个简单聊天室弄出来了。。虽然很简单,但是总归是有收获。
不多说,附上历程:
step 01:首先在vs端搭了一个简单的服务器,结合上一篇的内容做了些改进
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace 聊天室_scoket_tcp服务器
{
class Program
{
static List<Client> clientlists=new List<Client>();
/// <summary>
/// 广播信息
/// </summary>
/// <param name="message"></param>
public static void BroadcastMessage(string message)
{
var NotConnectClient = new List<Client>();//掉线线客户端集合
foreach (var client in clientlists)
{
if (client.Connected())//判断是否在线
{
client.SendMessage(message);
}
else
{
NotConnectClient.Add(client);
}
}
//将掉线的客户端从集合里移除
foreach (var temp in NotConnectClient)
{
clientlists.Remove(temp);
}
}
static void Main(string[] args)
{
Socket tcpServer=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPAddress ipAddress=IPAddress.Parse("172.25.14.165");
IPEndPoint ipEndPoint=new IPEndPoint(ipAddress,7799);
tcpServer.Bind(ipEndPoint);
Console.WriteLine("服务器开启....");
tcpServer.Listen(100);
//循环,每连接一个客户端建立一个Client对象
while (true)
{
Socket clientSocket = tcpServer.Accept();//暂停等待客户端连接,连接后执行后面的代码
Client client = new Client(clientSocket);//连接后,客户端与服务器的操作封装到Client类中
Console.WriteLine("一个客户端连接....");
clientlists.Add(client);//放入集合
}
}
}
}
step 02:新建一个类Client用来服务器端对客户端的数据进行处理接收与广播信息,然后在Program类中的Main()函数的while循环中创建Cilent对象,代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace 聊天室_scoket_tcp服务器
{
class Client
{
private Socket clientSocket;
private byte[] data=new byte[1024];//存储数据
public Client(Socket s)
{
clientSocket = s;
//开启一个线程 处理客户端的数据接收
Thread thread = new Thread(ReceiveMessage);
thread.Start();
}
private void ReceiveMessage()
{
//服务器一直接收客户端数据
while (true)
{
//如果客户端掉线,直接出循环
if (clientSocket.Poll(10,SelectMode.SelectRead))
{
clientSocket.Close();
break;
}
//接收信息
int length= clientSocket.Receive(data);
string message = Encoding.UTF8.GetString(data, 0, length);
//广播信息
Program.BroadcastMessage(message);
Console.WriteLine(message);
}
}
public void SendMessage(string message)
{
byte[] data = Encoding.UTF8.GetBytes(message);
clientSocket.Send(data);
}
public bool Connected()
{
return clientSocket.Connected;
}
}
}
step 03:在unity中搭建一个简单的布局(这个还在最后阻碍了我一下,发信息,显示面板没有内容,Text的这个控件被我弄的太窄了,都么有显示。)
布局中主要有以下几个控件:
step 04:界面搭好后,开始编写Unity客户端的代码,代码逻辑其实并没有什么变化,只是放到unity里运行而已。
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ChatClient : MonoBehaviour
{
public string ipaddress = "172.25.14.165";
public int port = 7799;
private Socket clientSocket;
public InputField MessageInput;
public Text MessageText;
private Thread thread;
private byte[] data=new byte[1024];// 数据容器
private string message = "";
void Start () {
ConnectToServer();
}
void Update () {
//只有在主线程才能更新UI
if (message!="" && message!=null)
{
MessageText.text +="\n"+ message;
message = "";
}
}
/**
* 连接服务器端函数
* */
void ConnectToServer()
{
clientSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//跟服务器连接
clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress),port));
//客户端开启线程接收数据
thread = new Thread(ReceiveMessage);
thread.Start();
}
void ReceiveMessage()
{
while (true)
{
if (clientSocket.Connected == false)
{
break;
}
int length=clientSocket.Receive(data);
message = Encoding.UTF8.GetString(data,0,length);
print(message);
}
}
void SendMessage(string message)
{
byte[] data=Encoding.UTF8.GetBytes(message);
clientSocket.Send(data);
}
public void OnSendButtonClick()
{
string value = MessageInput.text;
SendMessage(value);
MessageInput.text = " ";
}
/**
* unity自带方法
* 停止运行时会执行
* */
void OnDestroy()
{
//关闭连接,分接收功能和发送功能,both为两者均关闭
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
}
好了。以上就整个过程了。并不复杂,只是一直在熟悉Socket的逻辑。
我发布出来一个客户端,unity打开一个客户端,效果显示是可以通信的。
好了。完成了。终于可以睡觉了!!!(遗憾的是最后的运行图没有传上来)。