Created
April 5, 2016 16:16
-
-
Save jungrok5/0ffce72d65609f74127ec1f674e3fb3f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using GMTool.Sources.Config; | |
using GMTool.Sources.Data; | |
using GMTool.Sources.Network; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using System.Web; | |
namespace GMTool.Sources.Util | |
{ | |
public static class GMToolNetwork | |
{ | |
private static string szManagerServerIP; | |
private static int dwManagerServerPort; | |
private static List<OneTimeSession> sessionList = new List<OneTimeSession>(); | |
public static void SetCurrentManagerServer(string ip, int port) | |
{ | |
szManagerServerIP = ip; | |
dwManagerServerPort = port; | |
} | |
// 매니저 서버로 부터 응답을 받아야 하는 경우 | |
public static async Task SendToManagerServer(GMTool.Sources.GMToolDefine.GMToolCommand commandType, Packet packet, OneTimeSession.PacketHandler recvHandler) | |
{ | |
OneTimeSession session = new OneTimeSession(recvHandler); | |
sessionList.Add(session); | |
try | |
{ | |
using (Packet sendPacket = Packet.Alloc(CSProtocolID.CS_GM_TOOL_COMMAND_REQ)) | |
{ | |
sendPacket.WriteString(GMToolConfig.Instance.Config.GMToolCertificateKey); | |
sendPacket.WriteByte((byte)commandType); | |
sendPacket.WriteAppendData(packet); | |
await session.Send(szManagerServerIP, dwManagerServerPort, sendPacket); | |
} | |
} | |
catch (Exception e) | |
{ | |
sessionList.Remove(session); | |
session.PacketCallback -= recvHandler; | |
session.Dispose(); | |
throw e; | |
} | |
} | |
// 매니저 서버로 그냥 보내기만 하는 경우 | |
public static async Task SendToManagerServer(GMTool.Sources.GMToolDefine.GMToolCommand commandType, Packet packet) | |
{ | |
using (Packet sendPacket = Packet.Alloc(CSProtocolID.CS_GM_TOOL_COMMAND_REQ)) | |
{ | |
sendPacket.WriteString(GMToolConfig.Instance.Config.GMToolCertificateKey); | |
sendPacket.WriteByte((byte)commandType); | |
sendPacket.WriteAppendData(packet); | |
using (OneTimeSession session = new OneTimeSession()) | |
{ | |
await session.Send(szManagerServerIP, dwManagerServerPort, sendPacket); | |
} | |
} | |
} | |
public static void PacketHandler(OneTimeSession session, Packet packet) | |
{ | |
sessionList.Remove(session); | |
session.PacketCallback -= PacketHandler; | |
session.Dispose(); | |
if (packet.GetID() != (ushort)CSProtocolID.CS_GM_TOOL_COMMAND_ACK) | |
return; | |
GMToolDefine.GMToolCommand commandType; | |
byte bCommandType = packet.ReadByte(); | |
commandType = (GMToolDefine.GMToolCommand)bCommandType; | |
switch (commandType) | |
{ | |
case GMToolDefine.GMToolCommand.GetServerStatus: | |
{ | |
WorldInfoMgr.Instance.PopStatusPacket(packet); | |
} | |
break; | |
case GMToolDefine.GMToolCommand.GetServerCountInfo: | |
{ | |
short wServerID = packet.ReadShort(); | |
byte bWorldID = packet.ReadByte(); | |
short wServerType = packet.ReadShort(); | |
ServerInfo serverInfo = null; | |
if (wServerType == (short)GMToolDefine.SERVER_TYPE.AuthServer) | |
{ | |
serverInfo = WorldInfoMgr.Instance.GetAuthServer(wServerID); | |
} | |
else | |
{ | |
serverInfo = WorldInfoMgr.Instance.GetServer(wServerID); | |
} | |
if (serverInfo != null) | |
{ | |
CountInfoMgr countMgr = new CountInfoMgr(); | |
countMgr.PopInfoPacket(packet); | |
if (serverInfo.CountInfoMgrQueue.Count() >= 10) | |
serverInfo.CountInfoMgrQueue.Dequeue(); | |
serverInfo.CountInfoMgrQueue.Enqueue(countMgr); | |
} | |
} | |
break; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace GMTool.Sources.Util | |
{ | |
// http://msdn.microsoft.com/ko-kr/library/ff458671(v=vs.110).aspx | |
// http://msdn.microsoft.com/ko-kr/library/fs2xkftw(v=vs.80).aspx | |
// http://msdn.microsoft.com/ko-kr/library/8edha89s.aspx | |
// http://msdn.microsoft.com/ko-kr/library/xhbhezf4.aspx | |
// https://gist.github.com/ujentus/4001356 | |
// http://www.simpleisbest.net/category/NET-Framework-General.aspx | |
// http://kookiandkiki.blogspot.kr/2014/01/c-weakreference-idisosalbe.html | |
public abstract class ObjectPool<T> : IDisposable | |
where T : ObjectPool<T>, new() | |
{ | |
public static readonly int AUTO_INCREASE = -1; | |
public static readonly int NOT_USE_POOL = 0; | |
private static ThreadSafeQueue<T> pool; | |
private static Func<T> generator; | |
private static Func<T, T> destroyer; | |
protected bool createdByPool = false; | |
public static void CreatePool(int poolSize = -1, Func<T> generatorFunc = null, Func<T, T> destroyerFunc = null) | |
{ | |
generator = generatorFunc; | |
if (generator == null) | |
generator = () => { return new T(); }; | |
destroyer = destroyerFunc; | |
if (destroyer == null) | |
destroyer = (e) => | |
{ | |
e.ReUse(); | |
return e; | |
}; | |
if (poolSize != NOT_USE_POOL) | |
{ | |
pool = new ThreadSafeQueue<T>(); | |
if (poolSize != AUTO_INCREASE) | |
{ | |
PreAlloc(poolSize); | |
} | |
} | |
} | |
private static void PreAlloc(int count) | |
{ | |
for (int i = 0; i < count; ++i) | |
{ | |
T item = generator(); | |
item.createdByPool = true; | |
Free(item); | |
} | |
} | |
public static T Alloc() | |
{ | |
//if (generator == null) | |
// return new T(); | |
if (pool != null) | |
{ | |
T item = pool.Dequeue(); | |
if (item != null) | |
return item; | |
} | |
if (generator == null) throw new ArgumentNullException("generator", "ObjectPool<T>.CreatePool 함수를 통해서 풀을 먼저 생성하셔야 합니다."); | |
T newItem = generator(); | |
newItem.createdByPool = true; | |
return newItem; | |
} | |
public static void Free(T item) | |
{ | |
if (destroyer != null) | |
destroyer(item); | |
if (pool != null && item.IsCreatedByPool() == true) | |
pool.Enqueue(item); | |
} | |
public static void Clear() | |
{ | |
pool.Clear(); | |
generator = null; | |
destroyer = null; | |
} | |
public static int PoolCount() | |
{ | |
return pool.Count(); | |
} | |
// 풀에 의해 생성되었느냐 | |
public bool IsCreatedByPool() | |
{ | |
return createdByPool; | |
} | |
public abstract void Dispose(bool disposing); | |
public abstract void ReUse(); | |
~ObjectPool() | |
{ | |
Dispose(false); | |
} | |
public void Dispose() | |
{ | |
Dispose(true); | |
GC.SuppressFinalize(this); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using GMTool.Sources.Network; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace GMTool.Sources.Util | |
{ | |
public class OneTimeSession : IDisposable | |
{ | |
public delegate void ErrorHandler(); | |
public delegate void PacketHandler(OneTimeSession session, Packet packet); | |
public ErrorHandler ErrorCallback; | |
public PacketHandler PacketCallback; | |
private SocketAsyncEventArgs sendSAEA; | |
private SocketAsyncEventArgs recvSAEA; | |
private byte[] recvBuffer = new byte[4096]; | |
private byte[] m_Buffer; | |
private int m_BufferPos = 0; | |
private TcpClient client; | |
public OneTimeSession() | |
{ | |
sendSAEA = new SocketAsyncEventArgs(); | |
sendSAEA.Completed += new EventHandler<SocketAsyncEventArgs>(CompletedSend); | |
sendSAEA.UserToken = this; | |
recvSAEA = new SocketAsyncEventArgs(); | |
recvSAEA.Completed += new EventHandler<SocketAsyncEventArgs>(CompletedReceive); | |
recvSAEA.UserToken = this; | |
recvSAEA.SetBuffer(recvBuffer, 0, 4096); | |
m_Buffer = new byte[8192]; | |
} | |
public OneTimeSession(PacketHandler callback) : this() | |
{ | |
PacketCallback = callback; | |
} | |
~OneTimeSession() | |
{ | |
Dispose(false); | |
} | |
public void Dispose(bool disposing) | |
{ | |
// 관리되는 자원들 해제 | |
if (disposing) | |
{ | |
} | |
if (sendSAEA != null) | |
{ | |
sendSAEA.UserToken = null; | |
sendSAEA.Completed -= CompletedSend; | |
sendSAEA = null; | |
} | |
if (recvSAEA != null) | |
{ | |
recvSAEA.UserToken = null; | |
recvSAEA.Completed -= CompletedReceive; | |
recvSAEA = null; | |
} | |
if (client != null) | |
{ | |
client.Close(); | |
client = null; | |
} | |
} | |
public void Dispose() | |
{ | |
Dispose(true); | |
GC.SuppressFinalize(this); | |
} | |
public async Task Send(string ip, int port, byte[] data, int offset, int length) | |
{ | |
client = new TcpClient(); | |
await client.ConnectAsync(ip, port); | |
if (client.Connected == false) | |
{ | |
if (ErrorCallback != null) | |
ErrorCallback(); | |
return; | |
} | |
StartReceive(recvSAEA); | |
sendSAEA.SetBuffer(data, offset, length); | |
bool pending = client.Client.SendAsync(sendSAEA); | |
if (pending == false) | |
{ | |
ProcessSend(sendSAEA); | |
} | |
} | |
public async Task Send(string ip, int port, Packet packet) | |
{ | |
client = new TcpClient(); | |
await client.ConnectAsync(ip, port); | |
if (client.Connected == false) | |
{ | |
if (ErrorCallback != null) | |
ErrorCallback(); | |
return; | |
} | |
sendSAEA.SetBuffer(packet.GetData(), 0, packet.GetTotalPacketSize()); | |
bool pending = client.Client.SendAsync(sendSAEA); | |
if (pending == false) | |
{ | |
ProcessSend(sendSAEA); | |
} | |
} | |
private void OnReceived(byte[] buffer, int offset, int length) | |
{ | |
if (length >= m_Buffer.Length || m_BufferPos + length >= m_Buffer.Length) | |
return; | |
Array.Copy(buffer, offset, m_Buffer, m_BufferPos, length); | |
m_BufferPos += length; | |
if (m_BufferPos < Packet.HEADER_SIZE) | |
return; | |
int remainSize = m_BufferPos; | |
int readOffset = 0; | |
while (remainSize > 0) | |
{ | |
if (readOffset + Packet.HEADER_SIZE > m_BufferPos) | |
break; | |
ushort packetSize = (ushort)(BitConverter.ToUInt16(m_Buffer, readOffset + Packet.PACKET_SIZE_OFFSET) + Packet.HEADER_SIZE); | |
if (packetSize < 0 || packetSize >= Packet.BUFFER_SIZE) | |
return; | |
if (packetSize > remainSize) | |
break; | |
Packet recvPacket = new Packet(buffer, offset, length); | |
if (PacketCallback != null) | |
PacketCallback(this, recvPacket); | |
// 일회용 세션이니 한개가 조합되면 끊어버리자 | |
Disconnect(); | |
return; | |
//remainSize -= packetSize; | |
//readOffset += packetSize; | |
} | |
if (readOffset > 0) | |
{ | |
if (m_BufferPos > readOffset) | |
{ | |
Array.Copy(m_Buffer, readOffset, m_Buffer, 0, m_BufferPos - readOffset); | |
m_BufferPos -= readOffset; | |
} | |
else | |
{ | |
m_BufferPos = 0; | |
} | |
} | |
} | |
private bool IsConnected() | |
{ | |
if (client == null || client.Connected == false) | |
return false; | |
return true; | |
} | |
private void Disconnect() | |
{ | |
if (client != null) | |
{ | |
client.Close(); | |
client = null; | |
} | |
} | |
private void ProcessSend(SocketAsyncEventArgs e) | |
{ | |
if (IsConnected() == false) | |
return; | |
e.UserToken = null; | |
if (e.SocketError != SocketError.Success) | |
{ | |
Disconnect(); | |
return; | |
} | |
StartReceive(recvSAEA); | |
} | |
private void StartReceive(SocketAsyncEventArgs e) | |
{ | |
if (IsConnected() == false) | |
return; | |
try | |
{ | |
bool pending = client.Client.ReceiveAsync(e); | |
if (pending == false) | |
{ | |
ProcessReceive(e); | |
} | |
} | |
catch (Exception ex) | |
{ | |
if (ErrorCallback != null) | |
ErrorCallback(); | |
Disconnect(); | |
return; | |
} | |
} | |
private void ProcessReceive(SocketAsyncEventArgs e) | |
{ | |
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) | |
{ | |
OnReceived(e.Buffer, e.Offset, e.BytesTransferred); | |
} | |
else | |
{ | |
Disconnect(); | |
return; | |
} | |
StartReceive(e); | |
} | |
private void CompletedReceive(object sender, SocketAsyncEventArgs e) | |
{ | |
var session = e.UserToken as OneTimeSession; | |
if (session == null) | |
return; | |
if (e.LastOperation != SocketAsyncOperation.Receive) | |
throw new ArgumentException(string.Format("Invalid LastOperation:{0}", e.LastOperation)); | |
session.ProcessReceive(e); | |
} | |
private void CompletedSend(object sender, SocketAsyncEventArgs e) | |
{ | |
var session = e.UserToken as OneTimeSession; | |
if (session == null) | |
return; | |
if (e.LastOperation != SocketAsyncOperation.Send) | |
throw new ArgumentException(string.Format("Invalid LastOperation:{0}", e.LastOperation)); | |
session.ProcessSend(e); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using GMTool.Sources.Util; | |
using System; | |
using System.Collections; | |
using System.Text; | |
namespace GMTool.Sources.Network | |
{ | |
public partial class Packet : ObjectPool<Packet> | |
{ | |
public static readonly ushort BUFFER_SIZE = 8192; | |
public static readonly ushort HEADER_SIZE = 4; | |
public static readonly ushort ID_OFFSET = 0; | |
public static readonly ushort PACKET_SIZE_OFFSET = 2; | |
public ushort ID { get; private set; } | |
private ushort m_wPacketSize; | |
private ushort m_wReadOffSet; | |
private ushort m_wWriteOffSet; | |
private byte[] m_Data; | |
private ushort m_wPacketLen; | |
public bool HasError { get; private set; } | |
public static Packet AllocNoID() | |
{ | |
return Alloc((ushort)0); | |
} | |
public static Packet Alloc(CSProtocolID id) | |
{ | |
return Alloc((ushort)id); | |
} | |
public static Packet Alloc(byte[] data, int offset, int length) | |
{ | |
Packet packet = Alloc(); | |
packet.CopyData(data, offset, length); | |
return packet; | |
} | |
public static Packet Alloc(ushort id) | |
{ | |
Packet packet = Alloc(); | |
packet.SetID(id); | |
return packet; | |
} | |
public Packet() | |
{ | |
HasError = false; | |
m_wPacketSize = 0; | |
m_wReadOffSet = 0; | |
m_wWriteOffSet = 0; | |
} | |
public Packet(ushort id) : this() | |
{ | |
// 여기로 들어오는 경우는 풀이 아닌 직접 생성자로 생성하는 경우다 | |
SetID(id); | |
} | |
public Packet(CSProtocolID id) | |
: this((ushort)id) | |
{ | |
} | |
public Packet(byte[] data, int offset, int length) : this() | |
{ | |
// 여기로 들어오는 경우는 풀이 아닌 직접 생성자로 생성하는 경우다 | |
CopyData(data, offset, length); | |
} | |
public void CopyData(byte[] data, int offset, int length) | |
{ | |
if (data == null || length < HEADER_SIZE || length >= BUFFER_SIZE) | |
{ | |
HasError = true; | |
return; | |
} | |
ID = BitConverter.ToUInt16(data, offset + ID_OFFSET); | |
m_wPacketSize = BitConverter.ToUInt16(data, offset + PACKET_SIZE_OFFSET); | |
if (data.Length < (int)(offset + HEADER_SIZE + m_wPacketSize)) //이상하게 패킷이 오면 응급처리를 한다. | |
{ | |
m_wPacketSize = (ushort)(length - 4); | |
} | |
// 풀에 의해 생성되었다면 패킷버퍼 사이즈가 서로 상이하면 사용할때 문제가 되므로 | |
// 동일한 사이즈로 하기 위해 | |
if (IsCreatedByPool() == true) | |
{ | |
m_Data = new byte[BUFFER_SIZE]; | |
m_wPacketLen = (ushort)m_Data.Length; | |
} | |
else | |
{ | |
m_Data = new byte[length]; | |
m_wPacketLen = (ushort)length; | |
} | |
Array.Copy(data, offset, m_Data, 0, length); | |
} | |
private void CreateBuffer() | |
{ | |
m_Data = new byte[BUFFER_SIZE]; | |
m_wPacketLen = (ushort)m_Data.Length; | |
WritePacketSize(0); | |
} | |
public override void Dispose(bool disposing) | |
{ | |
Free(this); | |
} | |
public override void ReUse() | |
{ | |
ID = 0; | |
m_wPacketSize = 0; | |
m_wReadOffSet = 0; | |
m_wWriteOffSet = 0; | |
if (m_Data != null) | |
{ | |
Array.Clear(m_Data, 0, m_Data.Length); | |
m_wPacketLen = (ushort)m_Data.Length; | |
} | |
HasError = false; | |
} | |
public void WriteRemainData(Packet packet) | |
{ | |
Write(packet.GetData(), HEADER_SIZE + packet.m_wReadOffSet, packet.GetRemainDataSize()); | |
packet.m_wReadOffSet += packet.GetRemainDataSize(); | |
} | |
public void WriteAppendData(Packet packet) | |
{ | |
Write(packet.GetData(), HEADER_SIZE + packet.m_wReadOffSet, packet.GetRemainDataSize()); | |
} | |
public void WriteAppendData(Packet packet, int offset, ushort length) | |
{ | |
Write(packet.GetData(), offset, length); | |
} | |
public ushort GetRemainDataSize() | |
{ | |
return (ushort)(m_wPacketSize - m_wReadOffSet); | |
} | |
public void FinishReadData() | |
{ | |
m_wReadOffSet = m_wPacketSize; | |
} | |
public void Reset() | |
{ | |
m_wReadOffSet = 0; | |
} | |
public void DecreaseReadOffset(ushort offset) | |
{ | |
if (m_wReadOffSet > offset) | |
m_wReadOffSet -= offset; | |
else | |
m_wReadOffSet = 0; | |
} | |
public void IncreaseReadOffset(ushort offset) | |
{ | |
m_wReadOffSet += offset; | |
} | |
public void SetReadOffset(ushort offset) | |
{ | |
m_wReadOffSet = offset; | |
} | |
public ushort GetReadOffset() | |
{ | |
return m_wReadOffSet; | |
} | |
public ushort GetID() { return ID; } | |
public void SetID(CSProtocolID id) | |
{ | |
SetID((ushort)id); | |
} | |
public void SetID(ushort id) | |
{ | |
if (m_Data == null) | |
{ | |
CreateBuffer(); | |
} | |
ID = id; | |
WriteID(id); | |
} | |
public byte[] GetData() { return m_Data; } | |
public void SetData(byte[] data) | |
{ | |
Array.Copy(data, 0, m_Data, HEADER_SIZE, data.Length); | |
WritePacketSize((ushort)data.Length); | |
} | |
public ushort GetPacketSize() { return m_wPacketSize; } | |
public ushort GetTotalPacketSize() | |
{ | |
return (ushort)(HEADER_SIZE + m_wPacketSize); | |
} | |
private void WriteID(ushort id) | |
{ | |
if (m_Data == null) | |
m_Data = new byte[BUFFER_SIZE]; | |
byte[] data = BitConverter.GetBytes(id); | |
data.CopyTo(m_Data, ID_OFFSET); | |
} | |
private void WritePacketSize(ushort wPacketSize) | |
{ | |
byte[] data = BitConverter.GetBytes(wPacketSize); | |
data.CopyTo(m_Data, PACKET_SIZE_OFFSET); | |
} | |
public bool ValidWriteSize(ushort size) | |
{ | |
if (HEADER_SIZE + m_wWriteOffSet + size > m_wPacketLen) | |
{ | |
HasError = true; | |
return false; | |
} | |
return true; | |
} | |
public bool ValidReadSize(ushort size) | |
{ | |
if (HEADER_SIZE + m_wReadOffSet + size > m_wPacketLen) | |
{ | |
HasError = true; | |
return false; | |
} | |
return true; | |
} | |
private void Write(byte data) | |
{ | |
if (ValidWriteSize(sizeof(byte)) == false) | |
return; | |
m_Data[HEADER_SIZE + m_wWriteOffSet] = data; | |
m_wWriteOffSet += sizeof(byte); | |
m_wPacketSize += sizeof(byte); | |
WritePacketSize(m_wPacketSize); | |
} | |
private void Write(byte[] data, int offset, int length) | |
{ | |
if (ValidWriteSize((ushort)length) == false) | |
return; | |
if (data == null || data.Length < offset + length) | |
{ | |
HasError = true; | |
return; | |
} | |
if (BitConverter.IsLittleEndian == false) | |
{ | |
Array.Reverse(data, offset, length); | |
} | |
Array.Copy(data, offset, m_Data, HEADER_SIZE + m_wWriteOffSet, length); | |
m_wWriteOffSet += (ushort)length; | |
m_wPacketSize += (ushort)length; | |
WritePacketSize(m_wPacketSize); | |
} | |
private void Write(byte[] data) | |
{ | |
if (ValidWriteSize((ushort)data.Length) == false) | |
return; | |
if (BitConverter.IsLittleEndian == false) | |
{ | |
Array.Reverse(data); | |
} | |
data.CopyTo(m_Data, HEADER_SIZE + m_wWriteOffSet); | |
m_wWriteOffSet += (ushort)data.Length; | |
m_wPacketSize += (ushort)data.Length; | |
WritePacketSize(m_wPacketSize); | |
} | |
private byte[] Read(int offset, ushort length) | |
{ | |
if (ValidReadSize(length) == false) | |
return null; | |
byte[] data = new byte[length]; | |
Array.Copy(m_Data, offset, data, 0, length); | |
if (BitConverter.IsLittleEndian == false) | |
{ | |
Array.Reverse(data); | |
} | |
m_wReadOffSet += length; | |
return data; | |
} | |
public void WriteULong(ulong data) { Write(BitConverter.GetBytes(data)); } | |
public void WriteUInt(uint data) { Write(BitConverter.GetBytes(data)); } | |
public void WriteUShort(ushort data) { Write(BitConverter.GetBytes(data)); } | |
public void WriteDouble(double data) { Write(BitConverter.GetBytes(data)); } | |
public void WriteFloat(float data) { Write(BitConverter.GetBytes(data)); } | |
public void WriteByte(byte data) { Write(data); } | |
public void WriteBool(bool data) { Write(BitConverter.GetBytes(data)); } | |
public void WriteShort(short data) { Write(BitConverter.GetBytes(data)); } | |
public void WriteLong(long data) { Write(BitConverter.GetBytes(data)); } | |
public void WriteInt(int data) { Write(BitConverter.GetBytes(data)); } | |
public void WriteString(string data) | |
{ | |
if (string.IsNullOrEmpty(data) == false) | |
{ | |
//data = data.Trim(); | |
byte[] ConvData = System.Text.Encoding.Unicode.GetBytes(data); | |
if (ConvData.Length >= 1000) | |
{ | |
HasError = true; | |
return; | |
} | |
if (ValidWriteSize((ushort)ConvData.Length) == false) | |
return; | |
WriteUShort((ushort)ConvData.Length); | |
Write(ConvData); | |
} | |
else | |
{ | |
WriteUShort(0); | |
} | |
} | |
public void WriteByteData(byte[] data) | |
{ | |
// 문자열을 넘길땐 data를 Encoding.ASCII.GetBytes 변환 사용할것 | |
if (data != null) | |
{ | |
WriteUShort((ushort)data.Length); | |
Write(data); | |
} | |
else | |
{ | |
WriteUShort(0); | |
} | |
} | |
public void WriteDateTime(DateTime data) | |
{ | |
Write(BitConverter.GetBytes(data.ToBinary())); | |
} | |
public void WriteDateTimeYMDHMS(DateTime data) | |
{ | |
WriteUShort((ushort)data.Year); | |
WriteUShort((ushort)data.Month); | |
WriteUShort((ushort)data.Day); | |
WriteUShort((ushort)data.Hour); | |
WriteUShort((ushort)data.Minute); | |
WriteUShort((ushort)data.Second); | |
} | |
public byte ReadByte() | |
{ | |
if (ValidReadSize(sizeof(byte)) == false) | |
return 0; | |
byte read = m_Data[HEADER_SIZE + m_wReadOffSet]; | |
m_wReadOffSet += sizeof(byte); | |
return read; | |
} | |
public ulong ReadULong() | |
{ | |
if (ValidReadSize(sizeof(ulong)) == false) | |
return 0; | |
ulong read = BitConverter.ToUInt64(m_Data, HEADER_SIZE + m_wReadOffSet); | |
m_wReadOffSet += sizeof(ulong); | |
return read; | |
} | |
public uint ReadUInt() | |
{ | |
if (ValidReadSize(sizeof(uint)) == false) | |
return 0; | |
uint read = BitConverter.ToUInt32(m_Data, HEADER_SIZE + m_wReadOffSet); | |
m_wReadOffSet += sizeof(uint); | |
return read; | |
} | |
public ushort ReadUShort() | |
{ | |
if (ValidReadSize(sizeof(ushort)) == false) | |
return 0; | |
ushort read = BitConverter.ToUInt16(m_Data, HEADER_SIZE + m_wReadOffSet); | |
m_wReadOffSet += sizeof(ushort); | |
return read; | |
} | |
public double ReadDouble() | |
{ | |
if (ValidReadSize(sizeof(double)) == false) | |
return 0.0; | |
double read = BitConverter.ToDouble(m_Data, HEADER_SIZE + m_wReadOffSet); | |
m_wReadOffSet += sizeof(double); | |
return read; | |
} | |
public float ReadFloat() | |
{ | |
if (ValidReadSize(sizeof(float)) == false) | |
return 0.0f; | |
float read = BitConverter.ToSingle(m_Data, HEADER_SIZE + m_wReadOffSet); | |
m_wReadOffSet += sizeof(float); | |
return read; | |
} | |
public bool ReadBool() | |
{ | |
if (ValidReadSize(sizeof(bool)) == false) | |
return false; | |
bool read = BitConverter.ToBoolean(m_Data, HEADER_SIZE + m_wReadOffSet); | |
m_wReadOffSet += sizeof(bool); | |
return read; | |
} | |
public short ReadShort() | |
{ | |
if (ValidReadSize(sizeof(short)) == false) | |
return 0; | |
short read = BitConverter.ToInt16(m_Data, HEADER_SIZE + m_wReadOffSet); | |
m_wReadOffSet += sizeof(short); | |
return read; | |
} | |
public long ReadLong() | |
{ | |
if (ValidReadSize(sizeof(long)) == false) | |
return 0; | |
long read = BitConverter.ToInt64(m_Data, HEADER_SIZE + m_wReadOffSet); | |
m_wReadOffSet += sizeof(long); | |
return read; | |
} | |
public int ReadInt() | |
{ | |
if (ValidReadSize(sizeof(int)) == false) | |
return 0; | |
int read = BitConverter.ToInt32(m_Data, HEADER_SIZE + m_wReadOffSet); | |
m_wReadOffSet += sizeof(int); | |
return read; | |
} | |
public string ReadString() | |
{ | |
ushort wLen = ReadUShort(); | |
if (ValidReadSize(wLen) == false) | |
return string.Empty; | |
if (wLen != 0) | |
{ | |
string s = System.Text.Encoding.Unicode.GetString(m_Data, HEADER_SIZE + m_wReadOffSet, wLen); | |
m_wReadOffSet += wLen; | |
string ts = s.TrimEnd('\0'); | |
return ts; | |
} | |
else | |
return string.Empty; | |
} | |
public DateTime ReadDateTime() | |
{ | |
long read = ReadLong(); | |
return DateTime.FromBinary(read); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment