Unity3D网络通讯--Socket通讯之Tcp通讯
Posted 微卡智享
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D网络通讯--Socket通讯之Tcp通讯相关的知识,希望对你有一定的参考价值。
学更好的别人,
做更好的自己。
——《微卡智享》
前言
项目整理
微卡智享
链接:https://pan.baidu.com/s/18VXIeyQbGKasguHcoQQ5Tg
提取码:vg8n
项目代码
微卡智享
01
添加属性
02
连接和发送
03
异步接收
异步实现思路
SocketTcp代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class SocketTcp : MonoBehaviour
{
private static SocketTcp _instance;
//TCPClient
private TcpClient _tcpClient;
private NetworkStream _netStream;//得到网络流
//接收处理类
public class TransData
{
public TransData(Action<bool, string> action, int buffsize = 8192)
{
recvbuff = new byte[1000000];
tmpbuff = new byte[buffsize];
istrans = false;
actionResult = action;
recvsize = 0;
}
public byte[] tmpbuff;
public byte[] recvbuff;
public int recvsize;
public bool istrans;
public Action<bool, string> actionResult;
}
private string _ipadr;
private int _port;
public static SocketTcp Instance
{
get
{
if (_instance == null)
{
GameObject goRestful = new GameObject("SocketTcp");
_instance = goRestful.AddComponent<SocketTcp>();
}
return _instance;
}
}
public SocketTcp Connect(string ipadr, int port)
{
_ipadr = ipadr;
_port = port;
try
{
if (_tcpClient == null || !_tcpClient.Connected)
{
_tcpClient = new TcpClient(_ipadr, _port);
_tcpClient.ReceiveBufferSize = 8192;
_tcpClient.SendBufferSize = 8192;
_netStream = _tcpClient.GetStream();
}
}
catch (System.Exception)
{
_tcpClient.Close();
_tcpClient.Dispose();
Connect(ipadr, port);
}
return Instance;
}
public SocketTcp Send(string msg = "")
{
try
{
if (_netStream.CanWrite)
{
Byte[] sendBytes = Encoding.UTF8.GetBytes(msg);
_netStream.Write(sendBytes, 0, sendBytes.Length);
_netStream.Flush();
}
}
catch (System.Exception)
{
_tcpClient.Close();
_tcpClient.Dispose();
Connect(_ipadr, _port).Send(msg);
}
return Instance;
}
public SocketTcp Recv(Action<bool, string> action = null)
{
TransData trans = new TransData(action, _tcpClient.ReceiveBufferSize);
try
{
_netStream.BeginRead(trans.tmpbuff, 0, trans.tmpbuff.Length,
TcpDataReceived, trans);
}
catch (System.Exception)
{
_tcpClient.Close();
_tcpClient.Dispose();
Connect(_ipadr, _port).Recv(action);
}
return Instance;
}
private void TcpDataReceived(IAsyncResult ar)
{
int recv = 0;
TransData transData = (TransData)ar.AsyncState;
try
{
recv = _netStream.EndRead(ar);
}
catch
{
recv = 0;
}
//判断接收数为0,并且未在接收中
if (recv == 0 && !transData.istrans)
{
transData = new TransData(transData.actionResult, _tcpClient.ReceiveBufferSize);
_netStream.BeginRead(transData.tmpbuff, 0, transData.tmpbuff.Length,
TcpDataReceived, transData);
}
//已在接收了,再次接收为0,说明接收完了,直接调用
else if (recv == 0)
{
//执行回调函数
string resstr = Encoding.UTF8.GetString(transData.recvbuff);
transData.actionResult(transData.istrans, resstr);
}
//如果recv大于0,说明接收到了数据,修改接收值
else
{
transData.istrans = true;
byte[] buff = new byte[recv];
Buffer.BlockCopy(transData.tmpbuff, 0, buff, 0, recv);
Buffer.BlockCopy(buff, 0, transData.recvbuff, transData.recvsize, recv);
transData.recvsize += recv;
if (recv < transData.tmpbuff.Length)
{
//执行回调函数
string resstr = Encoding.UTF8.GetString(transData.recvbuff);
int strlen = resstr.IndexOf('\0');
if (strlen > 0)
{
resstr = resstr.Substring(0, strlen);
}
transData.actionResult(transData.istrans, resstr);
//执行完回调后重新初始化接收参数
transData = new TransData(transData.actionResult, _tcpClient.ReceiveBufferSize);
}
_netStream.BeginRead(transData.tmpbuff, 0, transData.tmpbuff.Length,
TcpDataReceived, transData);
}
}
}
调用方法
实现效果
完
扫描二维码
获取更多精彩
微卡智享
「 往期文章 」
以上是关于Unity3D网络通讯--Socket通讯之Tcp通讯的主要内容,如果未能解决你的问题,请参考以下文章