프로그램 소스/VB.NET
[VB.NET] 비동기 소켓통신(Socket) 서버(Server)
프로젝트빈
2020. 11. 27. 10:59
반응형
[VB.NET] 비동기 소켓통신 서버프로그램
- BeginRead 방식을 이용한 소켓통신 방식입니다.
■ 프로그램 예제소스
//=========== 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
■ 소켓통신 서버 프로그램
반응형