서버 통신을 기반으로 한 프로그래밍을 하려면 필수적으로 알아야 하는 개념 입니다. 서버와의 통신을 주고 받을 때 숫자나 텍스트의 형태로 통신을 주고 받을 텐데 이때 필요한 개념이기 때문입니다. 프로그래머 라면 알아야하는 필수적인 개념이기도 하며, 그만큼 중요하기도 합니다. 이번 시간에는 직렬화와 역직렬화가 무엇인지와 용도를 알아 보겠습니다. 또한 예시코드를 작성하여 깊이 이해 하는 시간을 갖도록 하겠습니다.
목차
[직렬화의 개념]
객체를 다른형식으로 변환하여 데이터를 저장하거나 전송하는 프로세스를 말합니다. C#의 경우 데이터를 텍스트의 형식으로 변환하여 데이터를 전송합니다. 특히 텍스트 형식 중 Json형태로 많이 변환합니다.
목적
- 데이터 저장
- 객체의 현재 상태를 저장하기 위해서 사용합니다. 이렇게 저장된 데이터는 다시 읽어와서 사용합니다. 유저의 정보를 저장했다가 로그인 시 해당 유저의 정보를 가져오는 예시가 있습니다.
- 데이터 전송
- 네트워크를 통해서 다른 시스템으로 전송하거나 통신을 위해서 많이 사용합니다. 채팅 시스템을 만들 때 유저간 서로 텍스트를 주고 받을 경우 많이 사용합니다.
- 복원 및 복구
- 프로그램이 중단 됐을 때 객체의 이전 상태를 복원하거나 복구하기 위해 사용 됩니다.
[역직렬화의 개념]
역직렬화는 직렬화의 반대 과정입니다. 직렬화된 데이터를 원래 데이터 구조를 복원하는 작업을 말합니다. c#에서는 json 형식의 텍스트를 다시 클래스의 형태로 되돌리는 형태가 주된 예시 입니다.
역할
- 데이터 복원
- 텍스트를 다시 클래스로 변환하는 과정 입니다.
- 데이터 읽기
- 네트워크로 전송된 데이터를 프로그램이 읽을 수 있는 형태로 변환 해줍니다. 채팅 시스템에서 서버를 통해 직렬화된 데이터를 다시 클래스 형태로 변환하여 읽을 수 있게 해주는 예시가 있습니다.
- 데이터 공유
- 다른 시스템과 데이터를 공유하고 객체를 전달하는데 사용 됩니다.
[직렬화의 종류]
이진 직렬화 (Binary Serialization)
System.Runtime.Serialization
네임스페이스를 사용하는 방법입니다. 이진 형식에서 클래스형식으로 또는 그반대로 변환합니다.
BinaryFormatter binaryFormatter = new BinaryFormatter();
using (FileStream stream = new FileStream("data.bin", FileMode.Create))
{
binaryFormatter.Serialize(stream, myObject);
}
using (FileStream stream = new FileStream("data.bin", FileMode.Open))
{
myObject = (MyClass)binaryFormatter.Deserialize(stream);
}
XML 직렬화 (XML Serialization)
System.Xml.Serialization
네임스페이스를 사용합니다. XML 형식에서 클래스 형식으로 또는 그 반대로 변환 합니다.
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyClass));
using (StreamWriter writer = new StreamWriter("data.xml"))
{
xmlSerializer.Serialize(writer, myObject);
}
using (StreamReader reader = new StreamReader("data.xml"))
{
myObject = (MyClass)xmlSerializer.Deserialize(reader);
}
JSON 직렬화
System.Text.Json
또는 Newtonsoft.Json(NuGet 패키지)을 사용하여 JSON 형식에서 클래스 형식으로 또는 그 반대로 변환합니다. 가장 많이 사용 되는 형식이기도 합니다.
string json = System.Text.Json.JsonSerializer.Serialize(myObject);
myObject = System.Text.Json.JsonSerializer.Deserialize<MyClass>(json);
위는 System.Text.Json 라이브러리를 사용한 예시 입니다.
string json = Newtonsoft.Json.JsonConvert.SerializeObject(myObject);
myObject = Newtonsoft.Json.JsonConvert.DeserializeObject<MyClass>(json);
위는 Newtonsoft.Json (Json.NET) 라이브러리를 사용한 예시 입니다.
[사용 예시 코드]
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
직렬화할 클래스 입니다. c#에서는 Serializable 어트리뷰트로 표시 되어야 지만 가능합니다.
class Program
{
static void Main()
{
// 객체 생성
Person person = new Person
{
Name = "John Doe",
Age = 30
};
// 데이터를 저장할 파일 경로
string filePath = "person.dat";
// 객체를 직렬화하여 파일에 저장
SerializeObject(person, filePath);
// 파일에서 객체를 역직렬화
Person deserializedPerson = DeserializeObject<Person>(filePath);
// 객체 출력
Console.WriteLine($"Name: {deserializedPerson.Name}");
Console.WriteLine($"Age: {deserializedPerson.Age}");
}
static void SerializeObject(object obj, string filePath)
{
using (FileStream stream = new FileStream(filePath, FileMode.Create))
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
}
}
static T DeserializeObject<T>(string filePath)
{
using (FileStream stream = new FileStream(filePath, FileMode.Open))
{
IFormatter formatter = new BinaryFormatter();
return (T)formatter.Deserialize(stream);
}
}
}
[주로 사용되는 곳은?]
전반적인 서버통신에 모두 사용된다고 생각하시면 됩니다. 구체적인 예시로는 채팅 시스템, 로그인 시 유저의 정보를 불러올 때, 다른 상대의 정보를 보는 등이 있습니다.
게임에서 사용되는 곳은 pvp 콘텐츠 제작 시 상대 유저의 정보를 가져온다 거나, 캐릭터가 레벨업할 경우 캐릭터 정보를 저장하는 등이 있습니다. 핵심은 비 휘발성 정보를 저장하는 것 입니다.
간단하게 말하면 서버 통신과 비 휘발성 정보를 저장할 때 사용된다고 보시면 됩니다.
[왜 굳이 데이터를 변환해서 서버와 통신을 할까?]
변환하지 않고 서버와 통신하면 안되는걸까? 라는 의문을 가지실 수 있을 텐데 결론적으로는 어렵다고 보면 됩니다. 이유는 서버와 클라이언트 프로그램간 쓰는 언어가 다른 경우가 아주 많기 때문입니다. 만약 서버와 클라이언트가 c#을 쓰고 있다면 상관없지만 그렇지 않을 경우가 많고 안정적이지도 않습니다. 그렇기 때문에 어디서든 사용될 수 있도록 텍스트나 이진형태로 많이 쓰이는 것 입니다. 쉽게 말하면 언어가 다른 두 민족이 대화를 할 때 통역사를 고용하듯이 통역사 역할을 하는 것이라고 보시면 됩니다.
[마무리]
이 개념은 처음 접할 시 생소한 개념이기도 합니다. 하지만 데이터를 기반으로한 프로그래밍을 하다보면 자연스럽게 익숙해집니다. 제가 소개한 개념과 사용 예시들을 보시고 기억해 두시면 사용하는데 무리가 없을 것 입니다. 데이터를 주고 받을 때 필요한 과정중 하나라고 이해 하시면 쉽게 받아 들이실 수 있을 겁니다.