⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 talker.vb

📁 Visual Basic.NET控件时尚编程百例
💻 VB
字号:
Imports System
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Threading
Imports System.Net.Sockets
Imports System.Windows.Forms

Class Talker
    Implements IDisposable
    '实现接口
    Public socket As socket
    '定义Socket
    Public reader As TextReader
    '定义读出流
    Public writer As TextWriter
    '定义写入流
    Public client As Boolean
    '标识程序是客户端还是服务器端
    Public endPoint As IPEndPoint
    'IP地址
    Public prevSendText As String
    '在此之前发出去的信息
    Public prevReceiveText As String
    '在此之前收到的信息
    Public statusText As String
    '连接状态
    Public statusObj As Status
    '定义Status类型变量

    Public Sub Dispose() Implements IDisposable.Dispose
        GC.SuppressFinalize(Me)
        If Not (reader Is Nothing) Then
            '这部分代码用来释放资源,销毁对象
            reader.Close()
            reader = Nothing
            '释放读出流对象
        End If
        If Not (writer Is Nothing) Then
            writer.Close()
            '释放写入流对象
            writer = Nothing
        End If
        If Not (socket Is Nothing) Then
            socket.Close()
            '释放Socket对象
            socket = Nothing
        End If
    End Sub

    Public Sub New(ByVal endPoint As IPEndPoint, ByVal client As Boolean)
        '构造函数
        Me.endPoint = endPoint
        Me.client = client
        socket = Nothing
        reader = Nothing
        writer = Nothing
        statusText = String.Empty
        prevSendText = String.Empty
        prevReceiveText = String.Empty
    End Sub

    Protected Overrides Sub Finalize()
        '析构
        Dispose()
        MyBase.Finalize()
    End Sub

    Friend Event Notifications(ByVal notify As Notification, ByVal data As Object)
    '定义【通知】事件,对notify进行处理

    Public Enum Notification
        '系统可能的通知
        Initialized = 1
        StatusChange
        ReceivedAppend
        ReceivedRefresh
        EndNotify
        ErrorNotify
    End Enum

    Public Enum Status
        '状态
        侦听
        已正常连接
    End Enum

    Public Sub Start()
        ThreadPool.QueueUserWorkItem(New System.Threading.WaitCallback _
        (AddressOf EstablishSocket))
        '将用户项排队到线程池,调用指定的委托,
        '并指定在接受线程池服务时要传递给委托的对象()
    End Sub

    Private Sub EstablishSocket(ByVal state As Object)
        Dim stream As NetworkStream
        '定义流
        stream = Nothing
        '初始化
        Try
            If Not client Then
                '如果不是客户端,则进行侦听
                Dim listener As Socket
                Try
                    listener = New Socket(AddressFamily.InterNetwork, _
                    SocketType.Stream, ProtocolType.Tcp)
                    '实例化Socket类
                    listener.Blocking = True
                    '指示Socket处于阻塞模式
                    listener.Bind(endPoint)
                    '绑定本地的IP地址
                    SetStatus(Status.侦听)
                    '显示状态
                    listener.Listen(0)
                    '侦听
                    socket = listener.Accept()
                    '处理传入的连接请求
                    listener.Close()
                    '关闭Socket连接
                    stream = New NetworkStream(socket)
                    '实例化流类
                    reader = New StreamReader(stream)
                    '实例化读出流类
                    writer = New StreamWriter(stream)
                    '实例化写入流类
                    writer.Write("WINTALK .NET")
                    writer.Flush()
                    '清理缓冲区,将所有的缓冲数据写入基础设备
                Catch e As SocketException
                    '如果已经存在了一个侦听端,那么这个端口作为客户端
                    If e.ErrorCode = 10048 Then
                        client = True
                        endPoint = New IPEndPoint _
                        (Dns.Resolve("127.0.0.1").AddressList(0), endPoint.Port)
                        '设置端口地址
                    Else
                        RaiseEvent Notifications _
                        (Notification.ErrorNotify, "初始化Socket时发生错误:" & ControlChars.CrLf & e.ToString())
                        '触发事件
                    End If
                End Try
            End If

            If client Then  '以客户端形式进行连接
                Dim temp As New Socket(AddressFamily.InterNetwork, _
                SocketType.Stream, ProtocolType.Tcp)
                '实例化Socket类
                temp.Blocking = True
                '指示Socket处于阻塞模式
                temp.Connect(endPoint)
                socket = temp
                socket.SetSocketOption(SocketOptionLevel.Socket, _
                SocketOptionName.ReceiveTimeout, 5000)
                socket.SetSocketOption(SocketOptionLevel.Socket, _
                SocketOptionName.SendTimeout, 5000)
                stream = New NetworkStream(socket)
                reader = New StreamReader(stream)
                writer = New StreamWriter(stream)
                Dim handshake(11) As Char
                '判断是否连接上,通过发出的 WINTALK .NET 消息来判断
                Try
                    If Not (reader.Read(handshake, 0, 12) > 0 And New _
                    String(handshake) = "WINTALK .NET") Then
                        socket.Close()
                        socket = Nothing
                    Else
                        socket.SetSocketOption(SocketOptionLevel.Socket, _
                        SocketOptionName.ReceiveTimeout, 0)
                        socket.SetSocketOption(SocketOptionLevel.Socket, _
                        SocketOptionName.SendTimeout, 0)
                    End If
                Catch
                    socket.Close()
                    socket = Nothing
                End Try
            End If
            If Not (socket Is Nothing) Then
                SetStatus(Status.已正常连接)
                RaiseEvent Notifications(Notification.Initialized, Me)
                '触发事件进行初始化
                ReceiveTalk() '开始收取信息
                RaiseEvent Notifications(Notification.EndNotify, "远程连接已经关闭")
            Else
                RaiseEvent Notifications(Notification.ErrorNotify, _
                "建立Socket失败,检查端口设置是否正确")
            End If
        Catch e As IOException
            Dim sockExcept As SocketException = _
            CType(e.InnerException, SocketException)
            If Not (sockExcept Is Nothing) And 10054 = sockExcept.ErrorCode Then
                RaiseEvent Notifications(Notification.EndNotify, "远程连接已经断开")
            Else
                RaiseEvent Notifications(Notification.ErrorNotify, "Socket 错误" & _
                ControlChars.CrLf & e.Message)
            End If
        Catch e As Exception
            RaiseEvent Notifications(Notification.ErrorNotify, "Socket 错误" & _
            ControlChars.CrLf & e.Message)
        End Try
    End Sub

    Public Sub SendTalk(ByVal newText As String)
        '向远程机器发送信息
        Dim send As String
        If prevSendText.Length <= newText.Length And _
        String.CompareOrdinal(newText, 0, prevSendText, 0, _
        prevSendText.Length) = 0 Then
            '判断是否是附加的字符串
            Dim append As [String] = newText.Substring(prevSendText.Length)
            send = String.Format("A{0}:{1}", append.Length, append)
        Else
            send = String.Format("R{0}:{1}", newText.Length, newText)
            '否则取代该字符串
        End If '
        writer.Write(send)
        '发送字符串
        writer.Flush()
        '清理缓冲区
        prevSendText = newText
        '保存字符串为后面作比较
    End Sub

    Private Sub SetStatus(ByVal statusObj As Status)
        Me.statusObj = statusObj
        '获取系统状态
        RaiseEvent Notifications(Notification.StatusChange, statusObj)
        '设置状态
    End Sub

    Private Sub ReceiveTalk()
        '从远程客户端获取信息
        Dim commandBuffer(19) As Char
        Dim oneBuffer(0) As Char
        Dim readMode As Integer = 1
        Dim counter As Integer = 0
        Dim textObj As New StringBuilder()
        While readMode <> 0
            If reader.Read(oneBuffer, 0, 1) = 0 Then
                readMode = 0
            Else
                Select Case readMode
                    Case 1
                        If counter = commandBuffer.Length Then
                            readMode = 0
                        End If
                        If oneBuffer(0) <> ":"c Then
                            commandBuffer(counter) = oneBuffer(0)
                            counter = counter + 1
                        Else
                            counter = Convert.ToInt32(New String(commandBuffer, 1, _
                            counter - 1))
                            If counter > 0 Then
                                readMode = 2
                                textObj.Length = 0
                            Else
                                If commandBuffer(0) = "R"c Then
                                    counter = 0
                                    prevReceiveText = String.Empty
                                    RaiseEvent Notifications _
                                    (Notification.ReceivedRefresh, prevReceiveText)
                                End If
                            End If
                        End If
                    Case 2
                        textObj.Append(oneBuffer(0))
                        counter = counter - 1
                        If counter = 0 Then
                            Select Case commandBuffer(0)
                                Case "R"c
                                    prevReceiveText = textObj.ToString()
                                    RaiseEvent Notifications _
                                    (Notification.ReceivedRefresh, prevReceiveText)
                                Case Else
                                    Dim newText As String
                                    newText = textObj.ToString()
                                    prevReceiveText += newText
                                    RaiseEvent Notifications _
                                    (Notification.ReceivedAppend, newText)
                            End Select
                            readMode = 1
                        End If
                    Case Else
                        readMode = 0
                End Select
            End If
        End While
    End Sub

End Class

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -