클라이언트에서 객체를 서버로 전송해서 DB에 저장하는 방법입니다
(클라이언트) 객체 -> 직렬화 -> 소켓 --- 소켓 -> 객체 -> DB저장 (서버)
이런 식으로 돌아갑니다.
데이터 타입을 변환하는 과정들이 있어서 사전지식이 몇 가지 필요합니다
1. MemoryStream
2. Object(객체)
3. Base64String
4. Byte[]
이 4가지 타입을 주로 다룹니다
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class MyConvert
{
// MemoryStream을 Object로 변환
public Object MemoryStreamToObject(MemoryStream ms)
{
BinaryFormatter binFmtr = new BinaryFormatter();
ms.Position = 0;
Object obj = binFmtr.Deserialize(ms) as Object;
return obj;
}
// MemoryStream을 byte[]로 변환
public byte[] MemoryStreamToByte(MemoryStream ms)
{
ms.Position = 0;
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, (int)ms.Length);
return buffer;
}
// MemoryStream을 Base64String로 변환
public string MemoryStreamToBase64String(MemoryStream ms)
{
ms.Position = 0;
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, (int)ms.Length);
string base64EncodedString = Convert.ToBase64String(buffer);
return base64EncodedString;
}
// Object를 MemoryStream으로 변환
public MemoryStream ObjectToMemoryStream(Object obj)
{
BinaryFormatter binFmtr = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
binFmtr.Serialize(ms, obj);
ms.Position = 0;
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, (int)ms.Length);
ms.Position = 0;
return ms;
}
// Object를 byte[]로 변환
public byte[] ObjectToByte(Object obj)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter binFmtr = new BinaryFormatter();
binFmtr.Serialize(ms, obj);
ms.Position = 0;
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, (int)ms.Length);
return buffer;
}
// Object를 Base64String로 변환
public string ObjectToBase64String(Object obj)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter binFmtr = new BinaryFormatter();
binFmtr.Serialize(ms, obj);
ms.Position = 0;
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, (int)ms.Length);
string base64EncodedString = Convert.ToBase64String(buffer);
return base64EncodedString;
}
// byte[]를 MemoryStream 으로 변환
public MemoryStream ByteToMemoryStream(byte[] buffer)
{
MemoryStream ms = new MemoryStream();
ms.Write(buffer, 0, buffer.Length);
ms.Position = 0;
return ms;
}
// byte[]를 Object로 변환
public Object ByteToObject(byte[] buffer)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter binFmtr = new BinaryFormatter();
ms.Write(buffer, 0, buffer.Length);
ms.Position = 0;
Object obj = binFmtr.Deserialize(ms) as Object;
return obj;
}
// byte[]를 Base64String 으로 변환
public string ByteToBase64String(byte[] buffer)
{
string base64EncodedString = Convert.ToBase64String(buffer);
return base64EncodedString;
}
// Base64String을 MemoryStream로 변환
public MemoryStream Base64StringToMemoryStream(string base64EncodedString)
{
MemoryStream ms = new MemoryStream();
byte[] buffer = Convert.FromBase64String(base64EncodedString);
ms.Write(buffer, 0, buffer.Length);
ms.Position = 0;
return ms;
}
// Base64String을 Object로 변환
public Object Base64StringToObject(string base64EncodedString)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter binFmtr = new BinaryFormatter();
byte[] buffer = Convert.FromBase64String(base64EncodedString);
ms.Write(buffer, 0, buffer.Length);
ms.Position = 0;
Object obj = binFmtr.Deserialize(ms) as Object;
return obj;
}
// Base64String을 byte[]로 변환
public byte[] Base64StringToByte(string base64EncodedString)
{
return Convert.FromBase64String(base64EncodedString);
}
}
다음 예제는 클라이언트가 객체를 서버로 전송후 DB에 넣고,
다시 서버가 DB에서 객체를 읽어서 클라이언트로 보내는 예제입니다
DB에 객체가 삽입될 memo 컬럼은 longtext 타입입니다
CREATE TABLE memo (
id VARCHAR(8),
memo LONGTEXT
);
DB는 mysql을 사용했습니다
DB마다 약간씩 차이가 있더군요
참고하십시오
------------- 서버 -------------
class Program
{
static void Main(string[] args)
{
MyConvert mc = new MyConvert();
Socket m_listenSocket;
Socket m_clientSocket;
IPEndPoint m_listenEP;
MyClass myClass = new MyClass();
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
Console.WriteLine("서버 시작");
m_listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_listenEP = new IPEndPoint(IPAddress.Any, 555);
m_listenSocket.Bind(m_listenEP);
m_listenSocket.Listen(10);
m_clientSocket = m_listenSocket.Accept();
// 클라이언트로부터 객체 수신
int LENGTH = 1024;
int OFFSET = 0;
byte[] socket_buffer = new byte[LENGTH];
while (true)
{
int rcvd = m_clientSocket.Receive(socket_buffer, OFFSET, LENGTH, 0);
Console.WriteLine("메세지 수신 : " + rcvd + "byte");
if (rcvd > 0)
{
ms.Write(socket_buffer, 0, rcvd);
}
if (rcvd < LENGTH)
{
break;
}
}
// 수신된 MemoryStream을 Base64String으로 변환
string base64EncodedString = mc.MemoryStreamToBase64String(ms);
// 객체 string을 DB에 삽입
MySqlConnection con = new MySqlConnection("server = localhost; uid=root; password=1234; database=memojang; pooling=false;");
MySqlCommand cmd = new MySqlCommand("UPDATE memo SET memo=?paramDATA WHERE id='dalili'", con);
cmd.Parameters.Add(new MySqlParameter("?paramDATA", MySql.Data.MySqlClient.MySqlDbType.LongText)).Value = base64EncodedString;
cmd.Connection.Open();
int result = cmd.ExecuteNonQuery();
Console.WriteLine("result = " + result);
cmd.Dispose();
con.Close();
// DB에서 불러오기
con = new MySqlConnection("server = localhost; uid=root; password=1234; database=memojang; pooling=false;");
cmd = new MySqlCommand("SELECT * FROM memo WHERE id='dalili'", con);
cmd.Connection.Open();
MySqlDataReader mdr = cmd.ExecuteReader();
mdr.Read();
// 객체 string을 byte로 변환
byte[] buffer2 = mc.Base64StringToByte(mdr.GetString(1));
// 객체 byte를 클라이언트로 send
m_clientSocket.Send(buffer2);
cmd.Dispose();
con.Close();
m_listenSocket.Close();
m_clientSocket.Close();
}
}
------------- 클라이언트 -------------
class Program
{
static void Main(string[] args)
{
MyConvert mc = new MyConvert();
Console.WriteLine("클라이언트 시작");
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect("localhost", 555);
MemoryStream ms = new MemoryStream();
BinaryFormatter binFmtr = new BinaryFormatter();
MyClass myClass = new MyClass();
myClass.ID = "test";
myClass.DATA = "hello world";
// 객체를 ms로 변환
ms = mc.ObjectToMemoryStream(myClass);
int LENGTH = (int)ms.Length;
int OFFSET = 0;
byte[] buffer = new byte[LENGTH];
while (true)
{
int rcvd = ms.Read(buffer, OFFSET, LENGTH);
Console.WriteLine("전송 : " + rcvd + "byte");
if (rcvd > 0)
{
socket.Send(buffer, 0, rcvd, 0);
}
else
{
break;
}
}
Console.WriteLine("전송완료");
// 서버 로부터 객체 수신
int LENGTH2 = 1024;
int OFFSET2 = 0;
byte[] socket_buffer = new byte[LENGTH2];
ms.Position = 0; //처음부터 다시 읽기 위해서
while (true)
{
int rcvd = socket.Receive(socket_buffer, OFFSET2, LENGTH2, 0);
Console.WriteLine("메세지 수신 : " + rcvd + "byte");
if (rcvd > 0)
{
ms.Write(socket_buffer, 0, rcvd);
}
if (rcvd < LENGTH2)
{
break;
}
}
Console.WriteLine("수신완료");
// ms 스트림을 객체로 변환
MyClass myClass2 = (MyClass) mc.MemoryStreamToObject(ms);
Console.WriteLine(myClass2.ID);
Console.WriteLine(myClass2.DATA);
ms.Close(); //소멸.
socket.Close();
}