C# Rookiss Part4 ๊ฒ์์๋ฒ : Serialization
๐โโ๏ธSerialization
์ง๋ ฌํ
- ๋ฉ๋ชจ๋ฆฌ ์์ ์ด๋ค ์ธ์คํด์ค๋ก ์กด์ฌํ๋ ์ ๋ฅผ ๋ฉ์ํ๊ฒ ๋ง๋ค์ด์ ๋ฒํผ์์ ๋ฐ์ด๋ฃ๋ ์์
: Serialization
- ์ธ์ด๋ธ ํ์ผ์ ๋ง๋ค ๋๋ serialization ์ฌ์ฉ
- ๋ฐ์ดํธ ๊ณ์ด์ ์๋ ์ ๋ฅผ ๊บผ๋ด ์ฐ๋ ๊ฒ : Deserialization
๐ช์ฐจ๊ทผ์ฐจ๊ทผ
-
Serialization1 - TryWriteBite(Span)
- ๋ฉ๋ชจ๋ฆฌ ์์ ์ด๋ค ์ธ์คํด์ค๋ก ์กด์ฌํ๋ ์ ๋ฅผ ๋ฉ์ํ๊ฒ ๋ง๋ค์ด์ ๋ฒํผ์์ ๋ฐ์ด๋ฃ๋ ์์
: Serialization
- ์ธ์ด๋ธ ํ์ผ์ ๋ง๋ค ๋๋ serialization ์ฌ์ฉ
-
๋ฐ์ดํธ ๊ณ์ด์ ์๋ ์ ๋ฅผ ๊บผ๋ด ์ฐ๋ ๊ฒ : Deserialization
- ํด๋ผ์์ ์๋ฒ๋ก ์ ๋ณด๋ฅผ ์ค ๋ : playerId ์ฃผ๊ธฐ
-
์๋ฒ์์ ํด๋ผ๋ก ์ ๋ณด๋ฅผ ์ค ๋ : hp, attack ์ฃผ๊ธฐ
-
Recvํ ๋ ๋ฐ์ ๋ฐฐ์ด์์ ๋ฝ์์ค๊ธฐ
- PlayerInfoReq๋ฅผ ๋ง๋ค์ด์ ํด๋ผ์์ ์๋ฒ๋ก ์ ๋ณด ( playerId)๋ฅผ ์ฃผ๋ ์ํฉ์ผ ๋
- SendBufferHelper.Open์ผ๋ก ๊ณต๊ฐ์ ์ด๊ณ BitConverter๋ก size packetId playerId๋ฅผ ๋ฐ์ดํธ ๋ฐฐ์ด๋ก ์ ์ฅ Open์ผ๋ก ์ด์ด์ค ArraySegment์ ๋ณต์ฌ๋ฅผ ํ๊ณ Close ํ Send ์์
- ์์ Send์ ๋จ์
- size packetId playerId๋ฅผ ๋ฐ์ดํธ ๋ฐฐ์ด๋ก ์ ์ฅํ๋ ๋ถ๋ถ์ด ๊ฐ๊ฐ ๋์ ์ผ๋ก ๋ฐฐ์ด์ ์๋ก ์์ฑํ ํ Copy๋ฅผ ํตํด OpenSegment์ ๋ฃ๋๊ฒ ์์ฌ์
- ๋ง๋ฐ๋ก OpenSegment์ ๋ฃ์ผ๋ฉด ์ข์ ๋ฏ => BitConverter.TryWriteBites( new Span
(s.Array, s.Offset, s.Count ), packet.size); ๋ฅผ ์ฌ์ฉ - TryWriteBites๋ ๊ฐ์ ๋ฃ์ ๋์ฐฉ์ง์ ๋ฃ์ ๊ฐ์ ์ธ์๋ก ๋ฐ๋๋ฐ ๋์ฐฉ์ง๋ฅผ Span์ด๋ผ๋ ๊ฒ์ผ๋ก ๋ฐ๋๋ค, bool๊ฐ์ ๋ฐํํ์ฌ success์ฌ๋ถ๋ฅผ ํ๋จ ํ ์ ์๋ค, Copy๋ถ๋ถ๊ณผ ๋ฐฐ์ด์ ๋ง๋๋ ๋ถ๋ถ์ ์ ๊ฑฐ
- size๋ ๊ฒฐ๊ตญ ๋ค ๊ณ์ฐํ ๋ค์ ์ ์ ์์ผ๋ฏ๋ก success &= BitConverter.TryWriteBites( new Span
(s.Array, s.Offset, s.Count ), packet.size);๋ ๋ง์ง๋ง์ ๋ฃ์ด ์ฃผ์ด์ผ ํ๋ค
- ๋ฉ๋ชจ๋ฆฌ ์์ ์ด๋ค ์ธ์คํด์ค๋ก ์กด์ฌํ๋ ์ ๋ฅผ ๋ฉ์ํ๊ฒ ๋ง๋ค์ด์ ๋ฒํผ์์ ๋ฐ์ด๋ฃ๋ ์์
: Serialization
-
Serialization2 - Serialize, Deserialize ๊ฐ์
-
Openํ TryWriteBytes๋ก ๋ฐ์ด๋ฃ์ด์ฃผ๋ ๋ถ๋ถ์ ํจ์ํํ๋ก ๋ง๋ค๊ธฐ -> public abstract ArraySegment
Write(), public abstract void Read(ArraySegment s) -
Write์ TryWriteBytes๋ถ๋ถ์ ๋ฃ์ด์ฃผ๊ธฐ
-
ArraySegment๋ operate == ๋ก ์ค๋ฒ๋ก๋ฉ์ ํด์ null๋ก ๊ตฌ๋ณ๊ฐ๋ฅ
-
Read๋ถ๋ถ์ size id๋ฅผ ์ฝ์ ๋ค์ ์ฌ์ฉํ๋ ๊ฒ ์ด๋ฏ๋ก size id๋ ์ฃผ์์ฒ๋ฆฌ, playerId๋ง ์ฌ์ฉ
-
ํจํท ํค๋์ ์๋ ๊ฐ์ ๋ฏฟ์ ์ ์๊ณ ์ฐธ๊ณ ๋ง ํด์ผ ๋จ
-
12๋ฐ์ดํธ๊ฐ ์์ผํ๋๋ฐ 4๋ฐ์ดํธ๋ง ์ ํจ๋ฒ์๋ผ๊ณ ์ง์ด์ฃผ์ด๋ ๋ค์ ๋ถ๋ถ์ด ๋ฐ์ดํฐ๊ฐ ๋จ์์์ผ๋ฏ๋ก 12๋ฐ์ดํธ๊น์ง์ ๋ด์ฉ์ด ์ถ๋ ฅ๋๊ณ size๋ 4๋ผ๊ณ ๋ฌ๋ค
-
=> Read๋ถ๋ถ ๋ง์ง๋ง์ BitConverter.ToInt64(new ReadOnlySpan
(s.Array, s.Offset + count, s.Count - count));๋ฅผ ์ถ๊ฐํ์ฌ ๋ฒ์๋ฅผ ์ด๊ณผํ ๋ ์๋ค์ Exeption์ด ๋จ๊ฒ ๋ง๋ ๋ค -
=> ์ด๋ ๊ฒ ํ๋ค๋ฉด ๋ง์ง๋ง์ size๊ฐ์ ์๊ฒ ์ค๋คํ๋๋ผ๋ ๋จ์ ๊ณต๊ฐ์ด ๋ถ์กฑํ๊ธฐ ๋๋ฌธ์ e๋ฐ์
-
-
-
Serialization3 - ๊ฐ๋ณ์ ์ธ ๋ฐ์ดํฐ
-
Span์ Sliceํ์ฉ : ์ฒซ SendBufferHelper.Open์ ArraySegment๋ฅผ Span์ผ๋ก ๋ค์ ๋ง๋คํ TryWriteByte๋ถ๋ถ์ Slice๋ก ๋ฃ์ด ๊ฐ๋ ์ฑ ๋์ด๊ธฐ, Slice๋ ๊ทธ ์์ฒด๊ฐ ๋ณํ๋ ๊ฒ์ด ์๋๋ผ ๊ฒฐ๊ณผ๊ฐ์ผ๋ก Span์ ๋ฐํํ๋ค -> ์ค์ง์ ์ผ๋ก s์ ๋ณํ๊ฐ ์๋ ๊ฒ์ ์๋๋ค
-
Read๋ถ๋ถ์ ReadOnlySpan์ผ๋ก ๋ง๋ค๊ธฐ
-
๊ฐ๋ณ์ ์ธ ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๋๊ธฐ๊ณ ์ถ์ถํ ๊น?
-
2๋ฐ์ดํธ์ง๋ฆฌ๋ก string์ ํฌ๊ธฐ(string len [2])๊ฐ ์ผ๋ง์ธ์ง ๋ณด๋ด๊ณ ํด๋นํ๋ ํฌ๊ธฐ์ ๋ฐ์ดํฐ๋ฅผ ์ด์ด์ ๋ณด๋ด๊ธฐ
-
name = โABCDโ ์ผ ๋ this.name.Length๋ฅผ ํ๋ฉด ํฌ๊ธฐ๋ 4์ด์ง๋ง ๋ฐ์ดํธ๋ก ๋ณํํ๋ฉด 8๋ฐ์ดํธ๋ก ๋๋ค : UTF-16์ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค => ushort nameLen = (ushort)Encoding.Unicode.GetByteCount(this.name);์ผ๋ก ํด์ผ๋๋ค
-
Read๋ถ๋ถ์ nameLen์ ToUInt16์ผ๋ก ๋ฝ์์ค๊ณ string๋ฐ์ดํฐ๋ Encoding.Unicode.GetString()์ ์ฌ์ฉํจ : ๋ฐ์ดํธ๋ฅผ string์ผ๋ก ๋ฐ๊ฟ์ค
-
-
Encoding.Unicode.GetString() => byte๋ฅผ string์ผ๋ก ๋ณํ. Encoding.Unicode.GetBytes() => string๋ฅผ byte์ผ๋ก ๋ณํ.
//string
//ushort nameLen = (ushort)Encoding.Unicode.GetByteCount(this.name);
//success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
//count += sizeof(ushort);
//Array.Copy(Encoding.Unicode.GetBytes(this.name), 0, segment.Array, count, nameLen);
//count += nameLen;
// ์์ ์ฝ๋๋ฅผ ๊ฐ์ ํ ๋ถ๋ถ
ushort nameLen = (ushort)Encoding.Unicode.GetBytes(this.name, 0, this.name.Length, segment.Array, segment.Offset + count + sizeof(ushort));
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
count += sizeof(ushort);
count += nameLen;
-
Serialization4 - List Serialization
-
๋ฆฌ์คํธ๋ ์ด๋ป๊ฒ ๋ฐ์ด์ฃผ๊ณ ์ถ์ถํ ๊น?
-
๋ฆฌ์คํธ๊ฐ int๊ฐ์๊ฒ์ ๋ฐ์ ๋ string์ ๋ฐ์ ๋ ์ฒ๋ผ ํฌ๊ธฐ๋ฅผ ๋ฐ๊ณ ๋ฐ์ด์ฃผ๊ณ ์ถ์ถ๊ฐ๋ฅ
-
ํ์ง๋ง ๊ตฌ์กฐ์ฒด๋ฅผ ๋ฐ์๊ฒฝ์ฐ ๋ฌ๋ผ์ง
-
๊ตฌ์ด์ ์ ํฌ๊ธฐ๋งํผ ๋ฐ์ด๋ฃ์ด์ฃผ๊ณ ๋ ๊ตฌ์กฐ์ฒด๋ด์ ์ธ์๋ค์ ์ํํ๋ฉด์ ๊ฐ๊ฐ ๋ฐ์ด๋ฃ์ด์ค
-
Read๋ถ๋ถ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์ธ์๊ฐ ๋ช๊ฐ๋ค์ด๊ฐ ์๋์ง ์ถ์ถํ๊ณ ์ํํ๋ฉด์ ๊ตฌ์กฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ถ์ถํ ์ถ๊ฐ ํด์ค
-
-
-
public struct SkillInfo
{
public int id;
public short level;
public float duration;
public bool Write(Span<byte> s, ref ushort count)
{
bool success = true;
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), id);
count += sizeof(int);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), level);
count += sizeof(short);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), duration);
count += sizeof(float);
return success;
}
public void Read(ReadOnlySpan<byte> s, ref ushort count)
{
id = BitConverter.ToInt32(s.Slice(count, s.Length - count));
count += sizeof(int);
level = BitConverter.ToInt16(s.Slice(count, s.Length - count));
count += sizeof(short);
duration = BitConverter.ToSingle(s.Slice(count, s.Length - count));
count += sizeof(float);
}
}
// skill list
skills.Clear();
ushort skillLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
for (int i = 0; i < skillLen; i++)
{
SkillInfo skill = new SkillInfo();
skill.Read(s, ref count);
skills.Add(skill);
}
// skill list
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), (ushort)skills.Count);
count += sizeof(ushort);
foreach (SkillInfo skill in skills)
success &= skill.Write(s, ref count);
-
Serialize๋ฅผ ํ ๋ ๋ณดํต ์ฌ์ฉํ๋๊ฒ์ ๊ตฌ๊ธ์์ ์ง์ํ๋ ํ๋กํ ๋ฒํ ํ๋ซ๋ฒํ ๋ ์ค ํ๋๋ฅผ ์ฌ์ฉํจ
-
ํ๋กํ ๋ฒํ๋ ์ค๊ฐ์ ์ด๋ค ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ณ ๊ทธ ์ธ์คํด์ค๋ฅผ ์ฑ์์ ๋ณํํ๋ ์์ ์ ํจ : ์ฑ๋ฅ์ ์ํด๊ฐ ์์ด๋ ์ฝ๋ฉ์ด ํธํจ, ์ง๊ด์ ์
-
ํ๋ซ๋ฒํ๋ ๋ง๋ฐ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํธ ๋ฐฐ์ด์ ์ง์ด ๋ฃ์
-
๐ช์ฝ๋
ServerSesion
namespace DummyClient
{
public abstract class Packet
{
public ushort size;
public ushort packetId;
public abstract ArraySegment<byte> Write();
public abstract void Read(ArraySegment<byte> s);
}
class PlayerInfoReq : Packet
{
public long playerId;
public string name;
public struct SkillInfo
{
public int id;
public short level;
public float duration;
public bool Write(Span<byte> s, ref ushort count)
{
bool success = true;
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), id);
count += sizeof(int);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), level);
count += sizeof(short);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), duration);
count += sizeof(float);
return success;
}
public void Read(ReadOnlySpan<byte> s, ref ushort count)
{
id = BitConverter.ToInt32(s.Slice(count, s.Length - count));
count += sizeof(int);
level = BitConverter.ToInt16(s.Slice(count, s.Length - count));
count += sizeof(short);
duration = BitConverter.ToSingle(s.Slice(count, s.Length - count));
count += sizeof(float);
}
}
public List<SkillInfo> skills = new List<SkillInfo>();
public PlayerInfoReq()
{
this.packetId = (ushort)PacketID.PlayerInfoReq;
}
public override void Read(ArraySegment<byte> segment)
{
ushort count = 0;
ReadOnlySpan<byte> s = new ReadOnlySpan<byte>(segment.Array, segment.Offset + count, segment.Count);
//ushort size = BitConverter.ToUInt16(s.Array, s.Offset);
count += sizeof(ushort);
//ushort id = BitConverter.ToUInt16(s.Array, s.Offset + count);
count += sizeof(ushort);
this.playerId = BitConverter.ToInt64(s.Slice(count, s.Length - count));
count += sizeof(long);
// string
ushort nameLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
this.name = Encoding.Unicode.GetString(s.Slice(count, nameLen));
count += nameLen;
// skill list
skills.Clear();
ushort skillLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
for (int i = 0; i < skillLen; i++)
{
SkillInfo skill = new SkillInfo();
skill.Read(s, ref count);
skills.Add(skill);
}
}
public override ArraySegment<byte> Write()
{
ArraySegment<byte> segment = SendBufferHelper.Open(4096);
ushort count = 0;
bool success = true;
Span<byte> s = new Span<byte>(segment.Array, segment.Offset + count, segment.Count - count);
//success &= BitConverter.TryWriteBytes(new Span<byte>(s.Array, s.Offset, s.Count), packet.size);
count += sizeof(ushort);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), this.packetId); // s๊ฐ ๋ณํ๋ ๊ฒ์ด ์๋๋ผ Sliceํ์ฌ Span์ ๋ง๋ค์ด์ ๋ฃ์ด์ค
count += sizeof(ushort);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), this.playerId);
count += sizeof(long);
//string
//ushort nameLen = (ushort)Encoding.Unicode.GetByteCount(this.name);
//success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
//count += sizeof(ushort);
//Array.Copy(Encoding.Unicode.GetBytes(this.name), 0, segment.Array, count, nameLen);
//count += nameLen;
ushort nameLen = (ushort)Encoding.Unicode.GetBytes(this.name, 0, this.name.Length, segment.Array, segment.Offset + count + sizeof(ushort));
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
count += sizeof(ushort);
count += nameLen;
// skill list
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), (ushort)skills.Count);
count += sizeof(ushort);
foreach (SkillInfo skill in skills)
success &= skill.Write(s, ref count);
success &= BitConverter.TryWriteBytes(s, count);
if (success == false)
return null;
return SendBufferHelper.Close(count);
}
}
public enum PacketID
{
PlayerInfoReq = 1,
PlayerInfoOk = 2,
}
class ServerSession : Session
{
public override void OnConnected(EndPoint endPoint)
{
Console.WriteLine($"OnConnected : {endPoint}");
PlayerInfoReq packet = new PlayerInfoReq() { playerId = 1001 , name = "ABCD"};
packet.skills.Add(new PlayerInfoReq.SkillInfo() { id = 101, level = 1, duration = 3.0f });
packet.skills.Add(new PlayerInfoReq.SkillInfo() { id = 201, level = 2, duration = 4.0f });
packet.skills.Add(new PlayerInfoReq.SkillInfo() { id = 301, level = 3, duration = 5.0f });
packet.skills.Add(new PlayerInfoReq.SkillInfo() { id = 401, level = 4, duration = 6.0f });
// ๋ณด๋ธ๋ค
//for (int i = 0; i < 5; i++)
{
ArraySegment<byte> s = packet.Write();
if (s != null)
Send(s);
}
}
public override void OnDisconnected(EndPoint endPoint)
{
Console.WriteLine($"OnDisconnected : {endPoint}");
}
public override int OnRecv(ArraySegment<byte> buffer)
{
string recvData = Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count);
Console.WriteLine($"[From Server] {recvData}");
return buffer.Count;
}
public override void OnSend(int numOfBytes)
{
Console.WriteLine($"Transferred bytes : {numOfBytes}");
}
}
}
ClientSession
namespace Server
{
public abstract class Packet
{
public ushort size;
public ushort packetId;
public abstract ArraySegment<byte> Write();
public abstract void Read(ArraySegment<byte> s);
}
class PlayerInfoReq : Packet
{
public long playerId;
public string name;
public struct SkillInfo
{
public int id;
public short level;
public float duration;
public bool Write(Span<byte> s, ref ushort count)
{
bool success = true;
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), id);
count += sizeof(int);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), level);
count += sizeof(short);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), duration);
count += sizeof(float);
return success;
}
public void Read(ReadOnlySpan<byte> s, ref ushort count)
{
id = BitConverter.ToInt32(s.Slice(count, s.Length - count));
count += sizeof(int);
level = BitConverter.ToInt16(s.Slice(count, s.Length - count));
count += sizeof(short);
duration = BitConverter.ToSingle(s.Slice(count, s.Length - count));
count += sizeof(float);
}
}
public List<SkillInfo> skills = new List<SkillInfo>();
public PlayerInfoReq()
{
this.packetId = (ushort)PacketID.PlayerInfoReq;
}
public override void Read(ArraySegment<byte> segment)
{
ushort count = 0;
ReadOnlySpan<byte> s = new ReadOnlySpan<byte>(segment.Array, segment.Offset + count, segment.Count);
//ushort size = BitConverter.ToUInt16(s.Array, s.Offset);
count += sizeof(ushort);
//ushort id = BitConverter.ToUInt16(s.Array, s.Offset + count);
count += sizeof(ushort);
this.playerId = BitConverter.ToInt64(s.Slice(count, s.Length - count));
count += sizeof(long);
// string
ushort nameLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
this.name = Encoding.Unicode.GetString(s.Slice(count, nameLen));
count += nameLen;
// skill list
skills.Clear();
ushort skillLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
for (int i = 0; i < skillLen; i++)
{
SkillInfo skill = new SkillInfo();
skill.Read(s, ref count);
skills.Add(skill);
}
}
public override ArraySegment<byte> Write()
{
ArraySegment<byte> segment = SendBufferHelper.Open(4096);
ushort count = 0;
bool success = true;
Span<byte> s = new Span<byte>(segment.Array, segment.Offset + count, segment.Count - count);
//success &= BitConverter.TryWriteBytes(new Span<byte>(s.Array, s.Offset, s.Count), packet.size);
count += sizeof(ushort);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), this.packetId); // s๊ฐ ๋ณํ๋ ๊ฒ์ด ์๋๋ผ Sliceํ์ฌ Span์ ๋ง๋ค์ด์ ๋ฃ์ด์ค
count += sizeof(ushort);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), this.playerId);
count += sizeof(long);
//string
//ushort nameLen = (ushort)Encoding.Unicode.GetByteCount(this.name);
//success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
//count += sizeof(ushort);
//Array.Copy(Encoding.Unicode.GetBytes(this.name), 0, segment.Array, count, nameLen);
//count += nameLen;
ushort nameLen = (ushort)Encoding.Unicode.GetBytes(this.name, 0, this.name.Length, segment.Array, segment.Offset + count + sizeof(ushort));
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
count += sizeof(ushort);
count += nameLen;
// skill list
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), (ushort)skills.Count);
count += sizeof(ushort);
foreach (SkillInfo skill in skills)
success &= skill.Write(s, ref count);
success &= BitConverter.TryWriteBytes(s, count);
if (success == false)
return null;
return SendBufferHelper.Close(count);
}
}
public enum PacketID
{
PlayerInfoReq = 1,
PlayerInfoOk = 2,
}
class ClientSession : PacketSession
{
public override void OnConnected(EndPoint endPoint)
{
Console.WriteLine($"OnConnected : {endPoint}");
//Packet packet = new Packet() { size = 100, packetId = 10 };
//ArraySegment<byte> openSegment = SendBufferHelper.Open(4096);
//byte[] buffer = BitConverter.GetBytes(packet.size);
//byte[] buffer2 = BitConverter.GetBytes(packet.packetId);
//Array.Copy(buffer, 0, openSegment.Array, openSegment.Offset, buffer.Length);
//Array.Copy(buffer2, 0, openSegment.Array, openSegment.Offset + buffer.Length, buffer2.Length);
//ArraySegment<byte> sendBuff = SendBufferHelper.Close(buffer.Length + buffer2.Length);
// 100๋ช
// 1 -> ์ด๋ํจํท์ด 100๋ช
// 100 -> ์ด๋ํจํท์ด 100 * 100 = 1๋ง
//Send(sendBuff);
Thread.Sleep(5000);
Disconnect();
}
public override void OnRecvPacket(ArraySegment<byte> buffer)
{
ushort count = 0;
ushort size = BitConverter.ToUInt16(buffer.Array, buffer.Offset);
count += 2;
ushort id = BitConverter.ToUInt16(buffer.Array, buffer.Offset + count);
count += 2;
switch ((PacketID)id)
{
case PacketID.PlayerInfoReq:
{
PlayerInfoReq p = new PlayerInfoReq();
p.Read(buffer);
Console.WriteLine($"PlayerInfoReq {p.playerId} {p.name}");
foreach (PlayerInfoReq.SkillInfo skill in p.skills)
{
Console.WriteLine($"skill ({skill.id}) ({skill.level}) ({skill.duration})");
}
}
break;
}
Console.WriteLine($"RecvPacketId {id}, Size {size}");
}
public override void OnDisconnected(EndPoint endPoint)
{
Console.WriteLine($"OnDisconnected : {endPoint}");
}
public override void OnSend(int numOfBytes)
{
Console.WriteLine($"Transferred bytes : {numOfBytes}");
}
}
}