Files
tianrunCRM/Assets/CoolapeFrame/Scripts/net/USocket.cs

337 lines
10 KiB
C#
Raw Normal View History

2020-07-04 14:41:25 +08:00
/*
********************************************************************************
*Copyright(C),coolae.net
*Author: chenbin
*Version: 2.0
*Date: 2017-01-09
*Description: socke,c# socketNumber据传输协议
*Others:
*History:
*********************************************************************************
*/
using UnityEngine;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Text;
using System.Threading;
namespace Coolape
{
#if !UNITY_WEBGL
public delegate void NetCallback(USocket socket, object obj);
public delegate void OnReceiveCallback(USocket socket, byte[] bytes, int len);
public class USocket
{
public string host;
public int port;
public Socket mSocket;
public static int mTmpBufferSize = 64 * 1024;
public byte[] mTmpBuffer = null;
private IPEndPoint ipe;
private NetCallback onConnectStateChgCallback;
private OnReceiveCallback onReceiveCallback;
private int failTimes = 0;
private bool isClosed = false;
public bool isActive = false;
public Timer timeoutCheckTimer;
public enum Errors
{
success = 0,
connectTimeout = 1,
IPEndPointIsNull = 2,
connectFailed = 3,
receivebytesLenError = 4,
serverClosedConnection = 5,
connectionIsClosed = 6,
sendAsynException = 7,
sendTimeout = 8,
}
public USocket(string host, int port)
{
init(host, port);
}
public void init(string host, int port)
{
isClosed = false;
this.host = host;
this.port = port;
IPAddress ip = null;
try
{
// is ip xx.xx.xx.xx
ip = IPAddress.Parse(host);
}
catch (Exception e)
{
// may be is dns
try
{
IPAddress[] address = Dns.GetHostAddresses(host);
if (address.Length > 0)
{
ip = address[0];
}
}
catch (Exception e2)
{
Debug.LogError(e2);
return;
}
}
if (ip == null)
{
Debug.LogError("Get ip is null");
return;
}
ipe = new IPEndPoint(ip, port);
if (ip.AddressFamily == AddressFamily.InterNetworkV6)
{
Debug.LogWarning("is ipv6");
mSocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
}
else
{
Debug.LogWarning("is ipv4");
mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
if (mTmpBuffer == null)
{
mTmpBuffer = new byte[mTmpBufferSize];
}
}
// 异步模式//////////////////////////////////////////////////////////////////
// 异步模式//////////////////////////////////////////////////////////////////
//public bool IsConnectionSuccessful = false;
public int timeoutMSec = 5000; //毫秒
public int maxTimeoutTimes = 3;
Timer connectTimeout = null;
public void connectAsync(NetCallback onConnectStateChgCallback)
{
try
{
isActive = false;
this.onConnectStateChgCallback = onConnectStateChgCallback;
if (ipe == null)
{
onConnectStateChg(false, Errors.IPEndPointIsNull);
return;
}
mSocket.BeginConnect(ipe, (AsyncCallback)connectCallback, this);
if (connectTimeout != null)
{
connectTimeout.Dispose();
connectTimeout = null;
}
connectTimeout = TimerEx.schedule((TimerCallback)connectTimeOut, null, timeoutMSec);
}
catch (Exception e)
{
Debug.LogError(e);
}
}
void connectTimeOut(object orgs)
{
if (isActive)
{
}
else
{
onConnectStateChg(false, Errors.connectTimeout);
}
}
protected void onConnectStateChg(bool connected, Errors retCode)
{
string msg = Enum.GetName(typeof(Errors), retCode);
Debug.LogWarning("connected=[" + connected + "]" + " retCode=[" + (int)retCode + "]" + " msg=[" + msg +"]");
if (isClosed)
{
return;
}
if (!connected && isActive)
{
if (retCode == Errors.serverClosedConnection)
{
close();
}
}
if (this.onConnectStateChgCallback != null)
{
ArrayList list = new ArrayList();
list.Add(connected);
list.Add((int)(retCode));
list.Add(msg);
this.onConnectStateChgCallback(this, list);
}
}
private void connectCallback(IAsyncResult ar)
{
// 从stateobject获取socket.
USocket client = (USocket)ar.AsyncState;
if (client.mSocket.Connected)
{
// 完成连接.
client.mSocket.EndConnect(ar);
client.isActive = true;
client.failTimes = 0;
client.onConnectStateChg(true, Errors.success);
}
else
{
client.onConnectStateChg(false, Errors.connectFailed);
}
if (connectTimeout != null)
{
connectTimeout.Dispose();
connectTimeout = null;
}
}
public void close()
{
try
{
isClosed = true;
isActive = false;
failTimes = 0;
if (mSocket != null)
{
mSocket.Close();
}
mSocket = null;
}
catch (Exception e)
{
Debug.LogError(e);
}
}
public void ReceiveAsync(OnReceiveCallback callback)
{
onReceiveCallback = callback;
ReceiveAsync();
}
private void ReceiveAsync()
{
try
{
// 从远程target接收Number据.
mSocket.BeginReceive(mTmpBuffer, 0, mTmpBufferSize, 0,
(AsyncCallback)ReceiveCallback, this);
}
catch (Exception e)
{
Debug.LogError(e);
}
}
private void ReceiveCallback(IAsyncResult ar)
{
USocket client = (USocket)ar.AsyncState;
try
{
if (client.timeoutCheckTimer != null)
{
client.timeoutCheckTimer.Dispose();
client.timeoutCheckTimer = null;
}
if (client.isActive)
{
client.failTimes = 0;
//从远程设备读取Number据
int bytesRead = client.mSocket.EndReceive(ar);
if (bytesRead > 0)
{
//Debug.Log("receive len==" + bytesRead);
// 有Number据存储.
onReceiveCallback(client, client.mTmpBuffer, bytesRead);
}
else if (bytesRead < 0)
{
client.onConnectStateChg(false, Errors.receivebytesLenError);
}
else
{
// 所有Number据读取完毕.
Debug.Log("receive zero=====" + bytesRead);
client.onConnectStateChg(false, Errors.serverClosedConnection);
return;
}
// 继续读取.
client.ReceiveAsync();
}
else
{
client.onConnectStateChg(false, Errors.connectionIsClosed);
}
}
catch (Exception e)
{
Debug.Log(e);
}
}
public void SendAsync(byte[] data)
{
try
{
if (data == null)
return;
// isOpen始发送Number据到远程设备.
if (this.timeoutCheckTimer == null)
{
this.timeoutCheckTimer = TimerEx.schedule((TimerCallback)sendTimeOut, null, timeoutMSec);
}
mSocket.BeginSend(data, 0, data.Length, 0,
(AsyncCallback)SendCallback, this);
}
catch (Exception e)
{
Debug.LogError("socket:" + e);
onConnectStateChg(false, Errors.sendAsynException);
}
}
public void sendTimeOut(object orgs)
{
failTimes++;
if (failTimes > maxTimeoutTimes)
{
onConnectStateChg(false, Errors.sendTimeout);
}
}
private void SendCallback(IAsyncResult ar)
{
USocket client = (USocket)ar.AsyncState;
// 完成Number据发送.
int bytesSent = client.mSocket.EndSend(ar);
if (bytesSent <= 0) //发送失败
{
sendTimeOut(null);
}
else
{
client.failTimes = 0;
}
}
}
#endif
}