첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestSolution.zip
0.01MB

[TestLibrary 프로젝트]

▶ SharedMemoryHelper.cs

using System.IO.MemoryMappedFiles;

namespace TestLibrary
{
    /// <summary>
    /// 공유 메모리 헬퍼
    /// </summary>
    public static class SharedMemoryHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 쓰기 - Write<T>(mapName, mapSize, offset, source)

        /// <summary>
        /// 쓰기
        /// </summary>
        /// <typeparam name="T">구조체 타입</typeparam>
        /// <param name="mapName">맵 명칭</param>
        /// <param name="mapSize">맵 크기</param>
        /// <param name="offset">위치</param>
        /// <param name="source">소스</param>
        public static void Write<T>(string mapName, long mapSize, long offset, T source) where T : struct
        {
            MemoryMappedFile file = MemoryMappedFile.CreateNew(mapName, mapSize);

            MemoryMappedViewAccessor accessor = file.CreateViewAccessor();

            accessor.Write<T>(offset, ref source);
        }

        #endregion
        #region 읽기 - Read<T>(mapName, offset)

        /// <summary>
        /// 읽기
        /// </summary>
        /// <typeparam name="T">구조체 타입</typeparam>
        /// <param name="mapName">맵 명칭</param>
        /// <param name="offset">오프셋</param>
        /// <returns>구조체</returns>
        public static T Read<T>(string mapName, long offset) where T : struct
        {
            using(MemoryMappedFile file = MemoryMappedFile.OpenExisting(mapName))
            {
                using(MemoryMappedViewStream stream = file.CreateViewStream(0, StructureHelper.SizeOf(typeof(T))))
                {
                    using(MemoryMappedViewAccessor accessor = file.CreateViewAccessor())
                    {
                        T target;

                        accessor.Read(offset, out target);

                        return target;
                    }
                }
            }
        }

        #endregion
    }
}

 

728x90

 

▶ StructureHelper.cs

using System;
using System.Collections.Generic;
using System.Reflection.Emit;
using System.Runtime.InteropServices;

namespace TestLibrary
{
    /// <summary>
    /// 구조체 헬퍼
    /// </summary>
    public static class StructureHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 타입 딕셔너리
        /// </summary>
        private static Dictionary<Type, int> _typeDictionary = new Dictionary<Type, int>();

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 크기 구하기 - SizeOf(type)

        /// <summary>
        /// 크기 구하기
        /// </summary>
        /// <param name="type">타입</param>
        /// <returns>크기</returns>
        public static int SizeOf(Type type)
        {
            int size;

            if(_typeDictionary.TryGetValue(type, out size))
            {
                return size;
            }

            size = GetSize(type);

            _typeDictionary.Add(type, size);

            return size;
        }

        #endregion

        #region 복사하기 - Copy(source, target)

        /// <summary>
        /// 복사하기
        /// </summary>
        /// <param name="source">소스 문자열</param>
        /// <param name="target">타겟 포인터</param>
        public unsafe static void Copy(string source, char* target)
        {
            char[] sourceCharArray = source.ToCharArray();

            Marshal.Copy(sourceCharArray, 0, new IntPtr(target), sourceCharArray.Length);
        }

        #endregion
        #region 문자열 구하기 - GetString(sourcePointer)

        /// <summary>
        /// 문자열 구하기
        /// </summary>
        /// <param name="sourcePointer">소스 포인터</param>
        /// <returns>문자열</returns>
        public unsafe static string GetString(char* sourcePointer)
        {
            return new string(sourcePointer);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region 크기 - GetSize(type)

        /// <summary>
        /// 크기 구하기
        /// </summary>
        /// <param name="type">타입</param>
        /// <returns>크기</returns>
        private static int GetSize(Type type)
        {
            DynamicMethod dynamicMethod = new DynamicMethod("SizeOfType", typeof(int), new Type[] { });

            ILGenerator ilGenerator = dynamicMethod.GetILGenerator();

            ilGenerator.Emit(OpCodes.Sizeof, type);
            ilGenerator.Emit(OpCodes.Ret);

            return (int)dynamicMethod.Invoke(null, null);
        }

        #endregion
    }
}

 

300x250

 

▶ Student.cs

using System;

namespace TestLibrary
{
    /// <summary>
    /// 학생
    /// </summary>
    public unsafe struct Student
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// ID
        /// </summary>
        public int ID;

        /// <summary>
        /// 성명
        /// </summary>
        public fixed char Name[20];

        /// <summary>
        /// 생성 시간
        /// </summary>
        public DateTime CreateTime;

        #endregion
    }
}

 

반응형

 

[TestServer 프로젝트]

▶ Program.cs

using System;

using TestLibrary;

namespace TestServer
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private unsafe static void Main()
        {
            Console.WriteLine("공유 메모리 쓰기를 실행합니다.");

            Student student = new Student();

            student.ID         = 1;
            student.CreateTime = DateTime.Now;

            StructureHelper.Copy("홍길동", student.Name);

            SharedMemoryHelper.Write("testMap", 1000, 0, student);

            Console.WriteLine($"ID        : {student.ID}");
            Console.WriteLine($"성명      : {StructureHelper.GetString(student.Name)}");
            Console.WriteLine($"생성 시간 : {student.CreateTime}");

            Console.ReadKey(false);
        }

        #endregion
    }
}

 

[TestClient 프로젝트]

▶ Program.cs

using System;
using System.Threading;

using TestLibrary;

namespace TestClient
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private unsafe static void Main()
        {
            Thread.Sleep(1000); // 테스트시 서버에서 공유 메모리를 쓰는 시간을 반영한다.

            Console.WriteLine("공유 메모리 읽기를 실행합니다.");

            Student student = SharedMemoryHelper.Read<Student>("testMap", 0);

            Console.WriteLine($"ID        : {student.ID}");
            Console.WriteLine($"성명      : {StructureHelper.GetString(student.Name)}");
            Console.WriteLine($"생성 시간 : {student.CreateTime}");

            Console.ReadKey(false);
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요