ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [VB.NET] 비동기 소켓통신(Socket) 서버(Server)
    프로그램 소스/VB.NET 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

     

    반응형

    댓글

Designed by Tistory.