C#
[C#] 네트워크(Network)를 통한 클래스(Class) 직렬화(Serialize) 역직렬화(Deserialize)
SSABI
2019. 11. 5. 10:54
반응형
네트워크를 통해서 클래스를 직렬화 역직렬화 하는 방법으로 다음과 같은 방법을 사용했습니다.
서버
This file contains hidden or 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
[Serializable] | |
public class Data | |
{ | |
public int Num; | |
public string Name; | |
public Data() { } | |
public Data(int num, string name) | |
{ | |
Num = num; | |
Name = name; | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
List<Data> datas = new List<Data>() | |
{ | |
new Data(1, "SSABI"), | |
new Data(2, "Simpson") | |
}; | |
TcpListener tcpListener = new TcpListener(IPAddress.Any, 6000); | |
tcpListener.Start(); | |
Console.WriteLine("Start Server"); | |
while (true) | |
{ | |
try | |
{ | |
TcpClient tcpClient = tcpListener.AcceptTcpClient(); | |
NetworkStream networkStream = tcpClient.GetStream(); | |
MemoryStream memoryStream = new MemoryStream(); | |
BinaryFormatter binaryFormatter = new BinaryFormatter(); | |
// 접속 정보 확인 | |
Socket clientSocket = tcpClient.Client; | |
IPEndPoint ipEndPoint = (IPEndPoint)clientSocket.RemoteEndPoint; | |
Console.WriteLine("Client IP : " + ipEndPoint.Address.ToString()); | |
binaryFormatter.Serialize(memoryStream, datas); | |
byte[] length = BitConverter.GetBytes(memoryStream.Length); | |
byte[] byteArray = memoryStream.ToArray(); | |
networkStream.Write(length, 0, 4); | |
networkStream.Write(byteArray, 0, byteArray.Length); | |
memoryStream.Close(); | |
networkStream.Close(); | |
tcpClient.Close(); | |
} | |
catch (System.Exception e) | |
{ | |
} | |
} | |
} | |
} |
클라이언트
This file contains hidden or 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
[Serializable] | |
public class Data | |
{ | |
public int Num; | |
public string Name; | |
public Data() { } | |
public Data(int num, string name) | |
{ | |
Num = num; | |
Name = name; | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
TcpClient tcpClient = new TcpClient(); | |
tcpClient.Connect("192.168.1.110", 6000); | |
NetworkStream networkStream = tcpClient.GetStream(); | |
BinaryFormatter binaryFormatter = new BinaryFormatter(); | |
byte[] lengthArray = new byte[4]; | |
networkStream.Read(lengthArray, 0, lengthArray.Length); | |
int length = BitConverter.ToInt32(lengthArray, 0); | |
byte[] byteArray = new byte[length]; | |
networkStream.Read(byteArray, 0, byteArray.Length); | |
MemoryStream memoryStream = new MemoryStream(byteArray); | |
memoryStream.Position = 0; | |
object obj = binaryFormatter.Deserialize(memoryStream); | |
List<Data> datas = (List<Data>)obj; | |
memoryStream.Close(); | |
networkStream.Close(); | |
tcpClient.Close(); | |
} | |
} |
하지만 위와 같은 방법으로 클래스를 직렬화 해서 역직렬화 했을 때
클라이언트쪽에서 다음과 같은 오류가 발생했습니다.

이 오류는 역직렬화 할때 클라이언트 쪽에서는 참조하는 어셈블리가 없기 때문에 클래스를 역직렬화 할 수가 없는 오류입니다. 같은 클래스를 정의해도 클라이언트 쪽에서는 어떤 클래스인지 인식할 수 없습니다. 오류를 해결하는 방법으로 DLL을 만들어서 어셈블리를 참조하는 방법으로 오류를 해결할 수도 있지만, 여기서는 Xml을 직렬화 한 후 역직렬화 하는 방식으로 설명드리겠습니다.
다음은 XmlSerializer 클래스를 이용한 클래스 직렬화 역직렬화를 방식입니다. NetworkStream에 List<Data>를 직렬화 한 후 클라이언트 쪽에서 역직렬화를 하면 됩니다.
클래스의 변수는 반드시 public으로 지정해야 변수에 있는 값이 전달이 됩니다. 또한 직렬화하려는 클래스는 매개변수가 없는 생성자를 가지고 있어야 합니다.
서버
This file contains hidden or 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
[Serializable] | |
public class Data | |
{ | |
public int Num; | |
public string Name; | |
public Data() { } | |
public Data(int num, string name) | |
{ | |
Num = num; | |
Name = name; | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
List<Data> datas = new List<Data>() | |
{ | |
new Data(1, "SSABI"), | |
new Data(2, "Simpson") | |
}; | |
TcpListener tcpListener = new TcpListener(IPAddress.Any, 6000); | |
tcpListener.Start(); | |
Console.WriteLine("Start Server"); | |
while (true) | |
{ | |
try | |
{ | |
// XML 버전 | |
TcpClient tcpClient = tcpListener.AcceptTcpClient(); | |
NetworkStream networkStream = tcpClient.GetStream(); | |
// 접속 정보 확인 | |
Socket clientSocket = tcpClient.Client; | |
IPEndPoint ipEndPoint = (IPEndPoint)clientSocket.RemoteEndPoint; | |
Console.WriteLine("Client IP : " + ipEndPoint.Address.ToString()); | |
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Data>)); | |
xmlSerializer.Serialize(networkStream, datas); | |
networkStream.Close(); | |
tcpClient.Close(); | |
} | |
catch (System.Exception e) | |
{ | |
} | |
} | |
} | |
} |
클라이언트
This file contains hidden or 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
[Serializable] | |
public class Data | |
{ | |
public int Num; | |
public string Name; | |
public Data() { } | |
public Data(int num, string name) | |
{ | |
Num = num; | |
Name = name; | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
TcpClient tcpClient = new TcpClient(); | |
tcpClient.Connect("127.0.0.1", 6000); | |
NetworkStream networkStream = tcpClient.GetStream(); | |
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Data>)); | |
List<Data> datas = (List<Data>)xmlSerializer.Deserialize(networkStream); | |
networkStream.Close(); | |
tcpClient.Close(); | |
foreach (Data data in datas) | |
Console.WriteLine(data.Num + ", " + data.Name); | |
} | |
} |

반응형