using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System;
using System.Net;
public class SocketClient
{
public delegate void ReceiveDataPocess(byte[] packetData);
public delegate void ErrorDataPocess();
ReceiveDataPocess receiveProcess;
ErrorDataPocess errorProcess;
private Socket m_Socket;
//리시브
private byte[] BeginReceiveData;
public SocketClient(ReceiveDataPocess _revProcess, ErrorDataPocess _errorProcess)
{
receiveProcess = _revProcess;
errorProcess = _errorProcess;
}
#region Conneting
public void StartConnect()
{
try
{
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string hostIp = "192.111.1.1";
int port = 11111;
IPAddress curAdd = null;
if (IPAddress.TryParse(hostIp, out curAdd))
{
Debug.Log("유효한 IP 입니다");
m_Socket.BeginConnect(hostIp, port, Callback_ConnectEnd, null);
}
}
catch(System.Exception ex)
{
ErrorException(ex);
}
}
void Callback_ConnectEnd(IAsyncResult result)
{
try
{
m_Socket.EndConnect(result);
//리시브 시작
Begin_Recieve();
Debug.Log("Socket Connect 성공 : " + m_Socket.Connected);
}
catch (System.Exception ex)
{
ErrorException(ex);
}
}
#endregion
#region Recieving
int BeginReceiveDataLength = 1024;
void Begin_Recieve()
{
try
{
if(m_Socket != null)
{
BeginReceiveData = new byte[BeginReceiveDataLength]; //서버로 부터 받을 데이터 크기
m_Socket.BeginReceive(BeginReceiveData, 0, BeginReceiveData.Length, SocketFlags.None, Callback_Received, BeginReceiveData);
}
}
catch (System.Exception ex)
{
ErrorException(ex);
}
}
void Callback_Received(IAsyncResult result)
{
if (m_Socket == null || !m_Socket.Connected) return;
try
{
SocketError socketErr;
int endReceiveLength = m_Socket.EndReceive(result,out socketErr);
if(endReceiveLength <= 0)
{
//다시 beginReceive
Begin_Recieve();
return;
}
if(socketErr == SocketError.Success)
{
byte[] receivedBuffer = (byte[])result.AsyncState;
//리시브 데이터 처리
ProcessRecievedData(endReceiveLength, receivedBuffer);
//다시 beginReceive
Begin_Recieve();
}
else
{
Debug.LogError("Recieve Error : " + socketErr.ToString());
return;
}
}
catch (System.Exception ex)
{
ErrorException(ex);
}
}
//리시브 데이터 처리
void ProcessRecievedData(int _endReceivedBufferLength, byte[] _receivedBuffer)
{
try
{
Debug.LogError("Recieved Success , endReceiveLength : " + _endReceivedBufferLength);
//실질 데이터 처리
receiveProcess(_receivedBuffer);
}
catch (System.Exception ex)
{
ErrorException(ex);
}
}
#endregion
#region Sending
public void Send_ProtocolData( byte[] sendBodyData)
{
try
{
if(m_Socket.Connected && m_Socket != null)
{
//비동기로 데이터 보내기
m_Socket.BeginSend(sendBodyData, 0, sendBodyData.Length, SocketFlags.None, Callback_SendProtocolData, null);
}
}
catch (System.Exception ex)
{
ErrorException(ex);
}
}
void Callback_SendProtocolData(IAsyncResult result)
{
try
{
m_Socket.EndSend(result);
}
catch (System.Exception ex)
{
ErrorException(ex);
}
}
#endregion
#region Error Exeption
// ============= Error Exeption ===============
void ErrorException(Exception ex)
{
Debug.LogError("Error_in Socket Processing : " + ex.ToString());
errorProcess();
DisConnect();
}
#endregion
#region Disconnect
public void DisConnect()
{
if (m_Socket == null) return;
if(m_Socket.Connected) m_Socket.Shutdown(SocketShutdown.Both); // 소켓을 비활성화 시킵니다.
m_Socket.Close(); //소켓을 닫습니다.
Debug.LogError("Close networking");
}
#endregion
}