프로그램 소스/VB.NET

[VB.NET] 비동기 소켓통신(Socket) 서버(Server)

프로젝트빈 2020. 11. 27. 10:59
반응형

[VB.NET] 비동기 소켓통신 서버프로그램

- BeginRead 방식을 이용한 소켓통신 방식입니다.

 

프로그램 사진1)

 

■ 프로그램 예제소스

 //=========== Form1 소스 ======================================================
 Private Sub B_시작_Click(sender As Object, e As EventArgs) Handles B_시작.Click
        Try
            T_서버오픈결과.Text = "오픈시도중...."
            PORT_NUM = CLng(T_서버포트.Text)
            GL_연결자Thread = New System.Threading.Thread(AddressOf Do연결자)
            GL_연결자Thread.IsBackground = True
            GL_연결자Thread.Start()
            T_서버오픈결과.Text = "성공"
        Catch ex As Exception
            T_서버오픈결과.Text = "실패"
        End Try
    End Sub
    
    Private Sub B_닫기_Click(sender As Object, e As EventArgs) Handles B_닫기.Click
        Try
            GL_연결자Thread.Abort()
            T_서버오픈결과.Text = "닫기성공"
        Catch ex As Exception
            T_서버오픈결과.Text = "닫기실패"
        End Try
    End Sub
    
    Private Sub Do연결자()
        Try
            GL_서버 = New TcpListener(PORT_NUM)
            GL_서버.Start()

            Dim 연결요청자 As System.Net.Sockets.TcpClient
            Do
                연결요청자 = GL_서버.AcceptTcpClient
                Dim connclient As New Conn_Client(연결요청자)
                AddHandler connclient.dataReceived, AddressOf 데이터받기
            Loop
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub
    
    //========== Socket 모듈부분 ================================================
    Module M_Socket
    Public PORT_NUM As Integer           '포트 번호

    Public GL_서버 As TcpListener
    Public GL_연결자Thread As Thread
    Public GL_연결 As Boolean
    Public GL_IP_Close As String 

    Public m_htClientTable As New Hashtable()      '접속한 클라이언트들 정보 저장
    Delegate Sub 데이터값(ByVal [Controls] As Object, ByVal [Data] As String)
    Private Sub 텍스트보이기(ByVal T As Object, ByVal 데이터 As String)
        Try
            T.text = 데이터
        Catch ex As Exception
            Dim D As New 데이터값(AddressOf 텍스트보이기)
            Form1.Invoke(D, New Object() {[T], [데이터]})
        End Try
    End Sub

    Function 서버시작() As String
        GL_연결자Thread = New System.Threading.Thread(AddressOf Do연결자)
        GL_연결자Thread.IsBackground = True
        GL_연결자Thread.Start()
        Return "성공"
    End Function

    Private Sub Do연결자()
        Try
            GL_서버 = New TcpListener(PORT_NUM)
            GL_서버.Start()
             
            Dim 연결요청자 As System.Net.Sockets.TcpClient
            Do
                연결요청자 = GL_서버.AcceptTcpClient
                Dim connclient As New Conn_Client(연결요청자)
                AddHandler connclient.dataReceived, AddressOf 데이터받기
            Loop
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub
    Private Sub 데이터받기(ByVal IP As String, ByVal 데이터 As String, ByVal sender As Conn_Client) '리시브 처리문
        텍스트보이기(Form1.T_리드, 데이터)
    End Sub

    Public Sub 연결자응답보내기(ByVal 샌드데이터 As String)
        Try
            Dim client As Conn_Client
            Dim entry As DictionaryEntry

            For Each entry In m_htClientTable
                client = CType(entry.Value, Conn_Client)
                client.SendData(샌드데이터)
            Next
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Private Sub 응답보내기(ByVal strMsg As String, ByVal sender As Conn_Client) '메세지보낸 사람에게 메세지 전송
        sender.SendData(strMsg)
    End Sub
End Module

Class Conn_Client
    Private 연결자 As TcpClient
    Private 연결자IP As String
    Private m_Writer As NetworkStream            '데이터 송신 스트림
    Private m_Buffer(BUFFER_SIZE) As Byte       '버퍼
    Private EndPoint As IPEndPoint
    Private Address As IPAddress
    Const BUFFER_SIZE As Integer = 1000

    Public Event dataReceived(ByVal IP As String, ByVal 데이터 As String, ByVal sender As Conn_Client)

    Public Sub New(ByVal client As System.Net.Sockets.TcpClient)
        연결자 = client
        EndPoint = client.Client.RemoteEndPoint
        Address = EndPoint.Address

        연결자IP = Address.ToString
        연결자확인(연결자IP, Me)

        m_Writer = 연결자.GetStream()

        연결자.GetStream.BeginRead(m_Buffer, 0, BUFFER_SIZE, AddressOf RecvData, Nothing)
    End Sub

    Public Sub 연결자확인(ByVal 연결자IP As String, ByVal client As Conn_Client)

        Dim IP확인 As Boolean = False
        Dim entry As DictionaryEntry

        For Each entry In m_htClientTable
            If entry.Key = 연결자IP Then
                IP확인 = True
            End If
        Next
        If IP확인 = True Then
            m_htClientTable.Remove(연결자IP)
        End If

        m_htClientTable.Add(연결자IP, client)
        IP확인 = False
    End Sub

    Private Sub RecvData(ByVal ar As IAsyncResult) '비동기 스트림 리시브
        Dim nRecv As Integer        '수신된 데이터의 크기
        Dim strRecv As String       '수신된 데이터

        Try
            SyncLock 연결자.GetStream
                '수시된 데이터의 크기
                nRecv = 연결자.GetStream.EndRead(ar)
            End SyncLock
            If nRecv = 0 Then
                연결자.Client.Disconnect(False)
            End If

            strRecv = System.Text.Encoding.UTF8.GetString(m_Buffer, 0, nRecv)

            RaiseEvent dataReceived(연결자IP, strRecv, Me)

            SyncLock 연결자.GetStream
                연결자.GetStream.BeginRead(m_Buffer, 0, BUFFER_SIZE, AddressOf RecvData, Nothing)
            End SyncLock

        Catch e As Exception
            GL_IP_Close = 연결자IP
        End Try
    End Sub

    Public Sub SendData(ByVal Data As String) '데이터 송신
        If 연결자.Connected = False Then Exit Sub
        SyncLock 연결자.GetStream
            Dim sendBytes() As Byte
            sendBytes = Encoding.UTF8.GetBytes(Data)
            m_Writer.Write(sendBytes, 0, sendBytes.Length)
            m_Writer.Flush()
           
            m_Writer.Flush()
        End SyncLock
    End Sub
End Class
    

 

 

■ 소켓통신 서버 프로그램 

 

BP_Center.exe
0.04MB

 

반응형