unity3d 简易socket通信,接收发送消息
程序员文章站
2022-03-26 14:41:25
...
using UnityEngine;
using System.Collections;
using System;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine.UI;
public class SocketClient : MonoBehaviour
{
public static SocketClient instance;
public int portNo = 9999;
private TcpClient _client;
byte[] data;
public string url = "127.0.0.1";
public void Awake()
{
instance = this;
}
public string idtext = "";
bool connect = false; //只允许登录一次
public void login()
{
if (idtext != "" && !connect)
{
connect = true;
this._client = new TcpClient();
this._client.Connect(url, portNo);
data = new byte[this._client.ReceiveBufferSize];
SendMessage(idtext);
this._client.GetStream().BeginRead(this.data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize),
ReceiveMessage, null);
}
else
{
Debug.Log("connect failed or connected");
}
}
public void ReceiveMessage(IAsyncResult ar)
{
try
{
int bytesRead;
bytesRead = this._client.GetStream().EndRead(ar);
if (bytesRead < 1)
{
return;
}
else
{
Debug.Log("Client_ReceiveMessage:"+System.Text.Encoding.UTF8.GetString(data, 0, bytesRead));
string message = System.Text.Encoding.UTF8.GetString(data, 0, bytesRead);
}
}
catch (Exception ex)
{
}
}
public void SendMessage(string message)
{
if (connect)
{
try
{
NetworkStream ns = this._client.GetStream();
byte[] dataMsg = System.Text.Encoding.UTF8.GetBytes(message);
ns.Write(dataMsg, 0, dataMsg.Length);
Debug.Log("Client_SendMessage:" + message);
ns.Flush();
}
catch (Exception ex)
{
Debug.Log("Excep:" + ex.Message);
}
}
else
{
Debug.Log("not connect");
}
}
int i = 0;
private void OnGUI()
{
if(GUI.Button(new Rect(150, 40, 100, 40), "Login"))
{
login();
}
if (GUI.Button(new Rect(150, 120, 100, 40), "SendMessage"))
{
SendMessage("_abc_"+i);
i++;
}
}
}
using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;
using System.Collections.Generic;
/// <summary>
/// scoket服务器监听端口脚本
/// </summary>
public class SocketServer : MonoBehaviour
{
private Thread thStartServer;//定义启动socket的线程
void Start()
{
thStartServer = new Thread(StartServer);
thStartServer.Start();//启动该线程
}
void Update()
{
}
private void StartServer()
{
const int bufferSize = 8792;//缓存大小,8192字节
IPAddress ip = IPAddress.Parse("127.0.0.1");
TcpListener tlistener = new TcpListener(ip, 9999);
tlistener.Start();
Debug.Log("Socket服务器监听启动......");
//TcpClient remoteClient = tlistener.AcceptTcpClient();//接收已连接的客户端,阻塞方法
//Debug.Log("客户端已连接!local:" + remoteClient.Client.LocalEndPoint + "<---Client:" + remoteClient.Client.RemoteEndPoint);
//NetworkStream streamToClient = remoteClient.GetStream();//获得来自客户端的流
do
{
GameClient user = new GameClient(tlistener.AcceptTcpClient());
Debug.Log(user._clientIP + " client logined");
//try //直接关掉客户端,服务器端会抛出异常
//{
// //接收客户端发送的数据部分
// byte[] buffer = new byte[bufferSize];//定义一个缓存buffer数组
// int byteRead = streamToClient.Read(buffer, 0, bufferSize);//将数据搞入缓存中(有朋友说read()是阻塞方法,测试中未发现程序阻塞)
// if (byteRead == 0)//连接断开,或者在TCPClient上调用了Close()方法,或者在流上调用了Dispose()方法。
// {
// Debug.Log("客户端连接断开......");
// break;
// }
// string msg = Encoding.Unicode.GetString(buffer, 0, byteRead);//从二进制转换为字符串对应的客户端会有从字符串转换为二进制的方法
// Debug.Log("接收数据:" + msg + ".数据长度:[" + byteRead + "byte]");
//}
//catch (Exception ex)
//{
// Debug.Log("客户端异常:" + ex.Message);
// break;
//}
}
while (true);
}
void OnApplicationQuit()
{
thStartServer.Abort();//在程序结束时杀掉线程,想起以前老谢给我讲的,起线程就像拉屎,完事一定要记得自己擦,系统不会给你擦,经测试不擦第二次启动unity会无响应
}
}
public class GameClient
{
public static Hashtable allClient = new Hashtable();
public static List<string> ipList = new List<string>();
private TcpClient _client;
public string _clientIP;
public string _clientNick;
private byte[] data;
public GameClient(TcpClient client)
{
this._client = client;
this._clientIP = client.Client.RemoteEndPoint.ToString();
if (allClient.Count <= 2)
{
allClient.Add(this._clientIP, this);
ipList.Add(this._clientIP);
data = new byte[this._client.ReceiveBufferSize];
client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), RceiveMessage, null);
this.sendMessage("login success");
}
else
{
this.sendMessage("connect num is max,so connect failed");
}
}
public void RceiveMessage(IAsyncResult ar)
{
int bytesread;
try
{
lock (this._client.GetStream())
{
bytesread = this._client.GetStream().EndRead(ar);
}
if (bytesread < 1)
{
allClient.Remove(this._clientIP);
Guangbo("server error");
return;
}
else
{
string messageReceived = System.Text.Encoding.UTF8.GetString(data, 0, bytesread);
Debug.Log("server recive :" + messageReceived);
if (!messageReceived.Contains("+"))
{
this._clientNick = messageReceived;
Debug.Log(this._clientIP + this._clientNick);
}
else
{
string[] strVect = messageReceived.Split('+');
}
lock (this._client.GetStream())
{
Debug.Log("lock (this._client.GetStream()):");
this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize),
RceiveMessage, null);
}
}
this.sendMessage("test_serverSend:"+System.DateTime.Now);
}
catch (Exception ex)
{
Debug.Log("something wrong");
allClient.Remove(this._clientIP);
Guangbo(this._clientNick + " leave");
}
}
public void Guangbo(string message)
{
Debug.Log("Guangbo:" + message);
foreach (DictionaryEntry c in allClient)
{
((GameClient)(c.Value)).sendMessage(message);
}
}
public void sendMessage(string message)
{
Debug.Log("server_sendMessage:" + this._clientNick + " ,send: " + message);
try
{
System.Net.Sockets.NetworkStream ns;
lock (this._client.GetStream())
{
ns = this._client.GetStream();
}
byte[] bytestosend = System.Text.Encoding.UTF8.GetBytes(message);
ns.Write(bytestosend, 0, bytestosend.Length);
ns.Flush();
}
catch (Exception ex)
{
Debug.Log("sendMessage_ex:"+ex.Message);
}
}
}
上一篇: 3D数学基础:图形与游戏开发笔记1
下一篇: GUI
推荐阅读
-
《Python核心编程》练习题之2-8:更新上一个练习的解决方案,修改它以使你的聊天服务现在成为全双工模式,意味着通信两端都可以发送并接收消息,并且二者相互独立
-
Python socket客户端接收消息和发送心跳包
-
Java Socket通信(一)之客户端程序 发送和接收数据
-
Java Socket通信(一)之客户端程序 发送和接收数据
-
《Python核心编程》练习题之2-8:更新上一个练习的解决方案,修改它以使你的聊天服务现在成为全双工模式,意味着通信两端都可以发送并接收消息,并且二者相互独立
-
unity3d 简易socket通信,接收发送消息
-
Python socket客户端接收消息和发送心跳包