C#/네트워크 관련
Selialization #1
tmd1
2024. 11. 23. 23:37
using ServerCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace DummyClient
{
class Packet
{
public ushort size;
public ushort id;
}
class PlayerInfoReq : Packet
{
public long playerId;
}
class PlayerInfoOk : Packet
{
public int hp;
public int attack;
}
public enum PacketID
{
PlayerInfoReq = 1,
PlayerInfoOk = 2
}
class ServerSession : Session
{
public override void OnConnected(EndPoint endPoint)
{
Console.WriteLine($"OnConnected : {endPoint}");
// 패킷을 최종적으로 보내기 전 까지는 사이즈를 알 수 없음
PlayerInfoReq packet = new PlayerInfoReq() { id = (ushort)PacketID.PlayerInfoReq, playerId = 1001 };
{
// 자동화를 위한 초석
ArraySegment<byte> s = SendBufferHelper.Open(4096);
ushort count = 0;
bool success = true;
// s.Count 보다 넣어주는게 크면 false
// TrtWriteBytes 이용해서 곧바로 ArraySement에 넣어줌
count += 2; // size 크기 미리 넣음(unshort)
success &= BitConverter.TryWriteBytes(new Span<byte>(s.Array, s.Offset + count, s.Count - count), packet.id);
count += 2;
success &= BitConverter.TryWriteBytes(new Span<byte>(s.Array, s.Offset + count, s.Count - count), packet.playerId);
count += 8;
// packet의 size 즉 count는 나중에 확정되므로 마지막에 보내줌
// count의 저장되어 있는 값은 패킷의 size(=12)고 size의 크기는 2(unshort)임
// count의 타입 유의 - count 타입이 int면 4 byte이므로 값이 덮어씌워 질 수 있음
// 물론 지금은 하드코딩이라서 그런거지만..
success &= BitConverter.TryWriteBytes(new Span<byte>(s.Array, s.Offset, s.Count), count);
ArraySegment<byte> sendBuff = SendBufferHelper.Close(count);
if(success)
Send(sendBuff);
}
}
public override void OnDisconnect(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}");
}
}
}
using ServerCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Server
{
class Packet
{
public ushort size;
public ushort id;
}
class PlayerInfoReq : Packet
{
public long playerId;
}
class PlayerInfoOk : Packet
{
public int hp;
public int attack;
}
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, id = 10 };
//// 최대 얼마만큼의 크기를 사용할 것인가
//ArraySegment<byte> openSegment = SendBufferHelper.Open(4096);
//// 바이트 배열로 바꿔줌
//byte[] buffer = BitConverter.GetBytes(packet.size);
//byte[] buffer2 = BitConverter.GetBytes(packet.id);
//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);
//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:
{
long playerId = BitConverter.ToInt64(buffer.Array, buffer.Offset + count);
count += 8;
Console.WriteLine($"PlayerInfoReq : {playerId}");
break;
}
}
Console.WriteLine($"ReceivePacketId : {id}, Size : {size}");
}
public override void OnDisconnect(EndPoint endPoint)
{
Console.WriteLine($"OnDisconnected : {endPoint}");
}
public override void OnSend(int numOfBytes)
{
Console.WriteLine($"Transferred bytes: {numOfBytes}");
}
}
}
Selialization을 위한 코드 수정
아직 완성 된 것이 아님.