[VB.net]메모리 매핑을 이용한 IPC(프로세스 간 통신) 이용하기

2017. 11. 14. 00:24Programming/VB.net

안녕하세요! Nitro입니다.

오늘은 프로그래밍에 꽤나 도움이 되는 지식을 들고 왔습니다.

바로 프로세스간 통신(IPC)방법인데요!


여러분들이 프로그램을 제작하다 보면, 프로그램과 프로그램이 통신해야하는 경우가 생길 수 있습니다.


하지만, 아무리 프로그램 1에서 A 라는 변수를 Public으로 선언해도, 프로그램 2에서는 A 라는 변수에 접근이 불가능합니다.

이는 서로 다른 프로세스들이 서로의 메모리 영역을 침법하여 발생하는 오류를 차단하기 위함으로 알고 있습니다.

그렇다면 위에서 언급했던것처럼, 프로그램이 서로 통신해야 할때는 어떻게 해야할까요?

몇몇의 사람들은 IPC의 존제를 모르고, 프로그램끼리 서로 서버 구축을 통하여 통신합니다.

하지만 IPC를 알게되면, 딱히 서버구축도 필요없고, 단 29줄의 소스코드면 손쉽게 공유할 수 있습니다.

마치 Form1과 Form2에서 사이로 공유된 변수(Public변수)가 있어서 통신이 되는것처럼,

프로그램 1과 프로그램 2가 서로 특정한 값을 공유하는것이죠.


그러나, .NET Framework 4 부터 메모리 매핑 메소드를 이용하여, exe 파일간 데이터 공유가 가능해졌습니다.
즉 IPC를 손쉽게 이용할 수 있다는것이죠.

상속 상위 계층은
System.Object
System.IO.MemoryMappedFiles
입니다.


(오타가 있습니다. 맵핑이 아니라 매핑인듯 합니다.)

이렇게 호출할 이름(매핑할 이름)을 적고, 내용을 적어준다음.


매핑된 이름을 불러오면, 저장된 내용이 출력됩니다.


개쩌는 부분은 이곳입니다!

바로 프로그램 1에서 적어놓은 IPC-Text라는 매핑을 프로그램 2 에서 호출할 수 있습니다.


요런식으로 서로 통신하게 되는것입니다.


소스코드를 작성하는 도중, 정리가 잘 되어있는 블로그를 찾아 그 블로그에서 소스코드를 가져왔습니다.

오류가 있었기에 추가와 수정을 하였습니다.

https://goo.gl/fBPSzY )

아레부터는 소스코드입니다.


[쓰기 부분]

    Public Sub MakeMemoryMappedFile(ByVal target As String, ByVal tarText As String)
        Dim File = MemoryMappedFile.CreateOrOpen(target, MaxSize)
        Dim bytes = New Byte() {}
        bytes = StrToByteArray(tarText)
        Using writer = File.CreateViewAccessor(0, bytes.Length)
            writer.WriteArray(0, bytes, 0, bytes.Length)
        End Using
    End Sub


[읽기 부분]

    Public Function ReadMemoryMappedFile(ByVal tarMem As String) As String
        Dim result As String = ""
        Try
            Using file = MemoryMappedFile.OpenExisting(tarMem)
                Using reader = file.CreateViewAccessor(0, MaxSize)
                    Dim bytes = New Byte(MaxSize) {}
                    reader.ReadArray(0, bytes, 0, bytes.Length)
                    result = System.Text.Encoding.UTF8.GetString(bytes)
                End Using
            End Using
            Return result
        Catch Ex As Exception
            Return result
        End Try
    End Function


[누락된 부분]

(참고했던 블로그에서 누락되었던 부분입니다.)

    Public Function StrToByteArray(ByVal str As String) As Byte()
        Dim encoding As New Text.UTF8Encoding()
        Return encoding.GetBytes(str)
    End Function


[쓰기 부분 사용법]

        MakeMemoryMappedFile(매핑할 이름, 내용)


[읽기 부분 사용법]

        MsgBox(ReadMemoryMappedFile(매핑된 이름)

[총 소스코드] 

Imports System.IO.MemoryMappedFiles
Public Class Form1
    Dim MaxSize As String = 10000
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MakeMemoryMappedFile(TextBox1.Text, TextBox2.Text)
    End Sub
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        MsgBox(ReadMemoryMappedFile(TextBox3.Text))
    End Sub
    Public Sub MakeMemoryMappedFile(ByVal target As String, ByVal tarText As String)
        Dim File = MemoryMappedFile.CreateOrOpen(target, MaxSize)
        Dim bytes = New Byte() {}
        bytes = StrToByteArray(tarText)
        Using writer = File.CreateViewAccessor(0, bytes.Length)
            writer.WriteArray(0, bytes, 0, bytes.Length)
        End Using
    End Sub
    Public Function ReadMemoryMappedFile(ByVal tarMem As String) As String
        Dim result As String = ""
        Try
            Using file = MemoryMappedFile.OpenExisting(tarMem)
                Using reader = file.CreateViewAccessor(0, MaxSize)
                    Dim bytes = New Byte(MaxSize) {}
                    reader.ReadArray(0, bytes, 0, bytes.Length)
                    result = System.Text.Encoding.UTF8.GetString(bytes)
                End Using
            End Using
            Return result
        Catch Ex As Exception
            Return result
        End Try
    End Function
    Public Function StrToByteArray(ByVal str As String) As Byte()
        Dim encoding As New Text.UTF8Encoding()
        Return encoding.GetBytes(str)
    End Function
End Class
MaxSize는 매핑할 내용의 최대 크기입니다.
목적에 따라 바꿔주세요.


이렇게 위 소스코드들은 IPC, 프로그램과의 데이터 통신을 더욱 쉽게 하도록 도와줍니다.


[예제 다운로드]

[참고]

https://msdn.microsoft.com/ko-kr/library/dd997372(v=vs.110).aspx

https://goo.gl/fBPSzY

한 컴퓨터 안에서 프로그램 2개가 데이터를 서로 공유해야 할 경우, 서버구축 말고, IPC를 사용해 보세요!
물론 보안이 약해 질 수도 있으니 보안프로그램이라면, 암호화를 필수로 진행하시기를 추천합니다.

뭐 제가 만들던 프로그램에서도 한때 사용하였습니다만..
그때는 멀티쓰래드를 몰라서 프로그램 하나를 더 만들고 IPC를 사용하여 멀티쓰래드처럼 사용했었죠..
말나온 김에 백그라운드 워커나 강의로 써봐야 할듯 하네요.

그럼 이상으로 Nitro 였구요!
다음 포스팅에서 뵙시다!
(오류, 오타 지적, 댓글 환영입니다!)


반응형