Unity Socket发送字符串(客户端)
程序员文章站
2022-07-13 21:57:14
...
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Net;
using System.Net.Sockets;
using System;
using System.Text;
public class Client : MonoBehaviour
{
public int Port;
public string Ip;
public Socket clientSocket;
MessageManager msg = new MessageManager();
private void Start()
{
ConnectServer();
}
void ConnectServer()
{
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
clientSocket.Connect(Ip, Port);
if (clientSocket.Connected == true)
{
Debug.Log("成功连接");
}
ReceiveMessage();
}
catch (Exception e)
{
Debug.LogWarning("无法连接到服务器" + e);
}
}
public void ReceiveMessage()
{
clientSocket.BeginReceive(msg.Data, msg.StartIndex, msg.RemainSize, SocketFlags.None, ReceiveCallBack, null);
}
private void ReceiveCallBack(IAsyncResult ar)
{
try
{
if (clientSocket == null || clientSocket.Connected == false) return;
int count = clientSocket.EndReceive(ar);
msg.ReadMessage(count);
//ReceiveMessageEvent();
ReceiveMessage();
}
catch (Exception e)
{
Debug.Log(e);
}
}
///<summary>
///接收消息
///</summary>
private void ReceiveMessageEvent()
{
while (true)
{
//在接受消息之前判断Socket是否连接
if (clientSocket.Connected == false) break;
//接受消息头(消息长度4字节)
int HeadLength = 4;
//存储消息头的所有字节数
byte[] recvBytesHead = new byte[HeadLength];
//如果当前需要接收的字节数大于0,则循环接收
while (HeadLength > 0)
{
byte[] recvBytes1 = new byte[4];
//将本次传输已经接收到的字节数置0
int iBytesHead = 0;
//如果当前需要接收的字节数大于缓存区大小,则按缓存区大小进行接收,相反则按剩余需要接收的字节数进行接收
if (HeadLength >= recvBytes1.Length)
{
iBytesHead = clientSocket.Receive(recvBytes1, recvBytes1.Length, 0);
}
else
{
iBytesHead = clientSocket.Receive(recvBytes1, HeadLength, 0);
}
//将接收到的字节数保存
recvBytes1.CopyTo(recvBytesHead, recvBytesHead.Length - HeadLength);
//减去已经接收到的字节数
HeadLength -= iBytesHead;
}
//接收消息体(消息体的长度存储在消息头的4至8索引位置的字节里)
byte[] bytes = new byte[4];
Array.Copy(recvBytesHead, 0, bytes, 0, 4);
int BodyLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(bytes, 0));
//存储消息体的所有字节数
byte[] recvBytesBody = new byte[BodyLength];
//如果当前需要接收的字节数大于0,则循环接收
while (BodyLength > 0)
{
byte[] recvBytes2 = new byte[BodyLength < 1024 ? BodyLength : 1024];
//将本次传输已经接收到的字节数置0
int iBytesBody = 0;
//如果当前需要接收的字节数大于缓存区大小,则按缓存区大小进行接收,相反则按剩余需要接收的字节数进行接收
if (BodyLength >= recvBytes2.Length)
{
iBytesBody = clientSocket.Receive(recvBytes2, recvBytes2.Length, 0);
}
else
{
iBytesBody = clientSocket.Receive(recvBytes2, BodyLength, 0);
}
//将接收到的字节数保存
recvBytes2.CopyTo(recvBytesBody, recvBytesBody.Length - BodyLength);
//减去已经接收到的字节数
BodyLength -= iBytesBody;
}
//一个消息包接收完毕,解析消息包
UnpackData(recvBytesHead, recvBytesBody);
}
}
/// <summary>
/// 解析消息包
/// </summary>
/// <param name="Head">消息头</param>
/// <param name="Body">消息体</param>
public void UnpackData(byte[] Head, byte[] Body)
{
byte[] bytes = new byte[4];
Array.Copy(Head, 0, bytes, 0, 4);
Debug.Log("接收到数据的长度:" + IPAddress.NetworkToHostOrder(BitConverter.ToInt32(bytes, 0)));
bytes = new byte[Body.Length];
for (int i = 0; i < Body.Length;)
{
byte[] _byte = new byte[4];
Array.Copy(Body, i, _byte, 0, 4);
i += 4;
int num = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(_byte, 0));
_byte = new byte[num];
Array.Copy(Body, i, _byte, 0, num);
i += num;
Debug.Log("接收到数据包中的数据有:" + Encoding.UTF8.GetString(_byte, 0, _byte.Length));
GameManager.Instance.IsShow(Encoding.UTF8.GetString(_byte, 0, _byte.Length));
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Text;
using System.Linq;
public class MessageManager
{
private byte[] data = new byte[1024];
private int startIndex = 0;
public byte[] Data
{
get { return data; }
}
public int StartIndex
{
get { return startIndex; }
}
public int RemainSize
{
get { return data.Length - startIndex; }
}
public void ReadMessage(int newDataAmount)
{
startIndex += newDataAmount;
while (true)
{
if (startIndex <= 4) return;
int count = BitConverter.ToInt32(data, 0);
if ((startIndex - 4) >= count)
{
string s = Encoding.UTF8.GetString(data, 4, count);
Debug.Log("解析出的数据:" + s);
Array.Copy(data, count + 4, data, 0, startIndex - 4 - count);
startIndex -= (count + 4);
}
else
{
break;
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
#region 单例
static GameManager _instance;
public static GameManager Instance
{
get
{
return _instance;
}
}
private void Awake()
{
_instance = this;
}
#endregion
public Text magText;
public bool isShow;
private string msg;
void Update()
{
if (isShow)
{
isShow = false;
magText.text += "\n" + msg;
}
}
public void IsShow(string sendMsg)
{
isShow = true;
msg = sendMsg;
}
}
推荐阅读