方言
青春的痕迹似乎正在以一种神秘的方式重回到我的生活中
在上一篇文章中主要介绍了socket异步通信实现的服务器端代码,下面我们来分析一下客户端代码:
那么在设计客户端代码时我们主要考虑哪些问题呢?
第一是如何接收数据,往往一次传输的数据量较大,但socket一次的传输量是1024个byte,因此需要对数据在发送端进行拆分,而在接收端进行组合。
第二是需要建立缓冲区,网络传输的速度肯定比我们处理数据的速度快。
大家如果需要使用这段代码,需要编写一下其中的ClassSetup类,该类包含每个工作站的配置信息,由于版权问题,在这里就不公开了。
客户端代码如下:
Public Class ClassServer

#Region "参数"

    
'以下是客户端到服务器端的消息开头 
    Const LOGININ As String = "10" '请求登陆的消息|||消息形式:10+自己的用户名 
    Const LOGINOUT As String = "11" '请求登出的消息|||消息形式:11+自己的用户名 
    Const GETULIST As String = "12" '请求获得在线用户列表|||消息形式:12+自己的用户名 
    Const P2PCONN As String = "13" '请求P2P连接的消息|||消息形式:13+自己的用户名+对方的用户名 
    Const HOLDLINE As String = "14" '保持连接.|||消息开式:14+自己的用户名 

    
'以下是服务器到客户端的消息开头 
    Const HVUSER As String = "20" '用户名已存在 
    Const GETUSER As String = "21" '在线用户列表|||消息格式:21+用户名+EP 
    Const MAKHOLD As String = "22" '打洞命令|||消息格式:22+IP 
    Const LOGINOK As String = "23" '登陆成功 
    Const SERVCLS As String = "24" '服务器关闭 
    Const MSGEND As String = "25" '消息结束 
    Const ONEOFF As String = "26" '一个客户端下线(超时下线)
    Const SEARCHCLIENT As String = "27" '探测各个客户端是否存在

    
'以下是客户端到客户端的消息开头 
    Const HOLDOK As String = "30" '打洞成功 
    Const CHATMSG As String = "31" '聊天消息 
    Const CHTMSGEND As String = "32" '聊天消息发送成功 
    Const GIVEMEDATA As String = "33" '添加数据订阅
    Const NODATASEND As String = "34" '取消数据订阅
    Const GETDEVINFO As String = "35" '获取工作站的基本信息

    
'以下是工作站发送到客户端的命令:
    Const RECDEVINFO As String = "45" '工作站发送给服务器的设备配置信息
    Const DATA As String = "40"       '表示发送的是数据信息,由工作站发送给客户端

    
'以下是客户端的命名 
    Const EXITPRO As String = "EXIT" '退出命令 
    Const SHOWULIST As String = "SHOWUSER" '显示在线用户 
    Const HELP As String = "HELP" '显示帮助 
    Const SEND As String = "SEND" '发送消息 

    
'Const OldData As String = "40"

#End Region

#Region "全局变量"

    
Delegate Sub myMethodDelegate(ByRef myInData As Byte()) '登陆时用的事件 
    Dim msgSendEnd As Boolean = False '消息是否发送成功,若发送成功,则会返回结束消息 
    Dim ThListen As New Thread(AddressOf listen) '监听的线程 
    Dim ThSend As Thread = Nothing
    
Dim ClientSocket As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) '客户端套节字的定义 
    Public username As String '当前用户名 
    Dim ServerEP As IPEndPoint '服务器的IPEP 
    Dim holdBytes As [Byte]() = Encoding.Unicode.GetBytes(HOLDLINE & username) '和服务器保持连接连接时用到的byte数组 
    Dim getUrecCount As Integer
    
Dim testHold As Boolean = False
    
Dim testChat As Boolean = False
    
Private receiveDone As ManualResetEvent '在登陆时用来阻塞线程,等待收到数据 
    Private sendDone As ManualResetEvent '用来阴塞发送消息的线程.等待收到回送的确认消息  
    Private holdDone As ManualResetEvent '用来阻塞打洞时的线程 
    Private chatDone As ManualResetEvent '用来阻塞发送聊天消息时的线程 
    Public Connected As Boolean = True   '用来表示是否和服务器连接成功
    Dim timerDelegate As New TimerCallback(AddressOf holdonline) '为保持在线状态弄得 
    Private mytimer As Timer
    
Public on_off As Boolean = False    '表示发送开关是否打开,有主任端连接即打开此开关,所有连接的主任端下线后即关闭
    Public SendDataList As ArrayList
    
Const movelenth As Integer = 509 '最大为511,加上标志位为512,乘以2为传送的最大字节数:1024
    Private sw As StreamWriter
    
Private dealing As Boolean = False
    
Private ReceiveDataList As DataQueue
    
'此数为减去头一个标志位(表示此段是否结束:0表示未结束;1表示结束)剩余的字符长度
#End Region

#Region "方法"

    
Public Event SendDDIinfo(ByVal TgIP As IPEndPoint)
    
Public Event NetWorkError(ByVal ErrStr As String)

    
'主函数,程序入口,放到splash中运行: 
    Sub New()
        
Try
            
If register.Reg.GetKey("ServerIP"= "" Then
                ServerEP 
= New IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000)
            
Else
                ServerEP 
= New IPEndPoint(IPAddress.Parse(register.Reg.GetKey("ServerIP")), 11000)  '正式版本专用,从注册表读取服务器地址
            End If
            sw 
= New StreamWriter(Directory.GetCurrentDirectory & "\DataServer.log"True)
            
AddHandler SendDDIinfo, AddressOf SendBasicInfo
            
'********测试专用,测试版本不读注册表,本机就是服务器!********
            'If getIdOfLocalhost() = "" Then
            '    '获取不到本机地址则退出
            '    RaiseEvent NetWorkError("找不到存在的连接")
            '    Exit Sub
            'End If
            '假设本机只有一块网卡,邦定一个ip地址和端口(5555)
            '正式版从注册表中读取GUID作为名称:
            '模拟版本获取主机名为登录名称:
            username = "DataServer " & Dns.GetHostName
            
Dim LocalEP As New IPEndPoint(IPAddress.Any, 5555)
            ClientSocket.Bind(LocalEP)      
'绑定本机端口
            ReceiveDataList = New DataQueue
            
'根据注册表中的ServerIp,向指定的服务器端口(11000)登录:
            Dim i As Int16 = 1
            
While Not Login()
                
If i > 2 Then      '三次登录失败,则退出循环,直接帮定本机ip的5555端口。保证可以正常通讯
                    Me.Connected = False
                    
RaiseEvent NetWorkError("登录失败!")
                    
Exit While
                
End If
                i 
+= 1
            
End While
            
'登陆成功后.用一个timer,每隔50秒向服务器发送消息,保持在线状态跟在主机注册的端口 
            mytimer = New Timer(timerDelegate, Nothing1000050000)
            ThListen.Start()
            SendDataList 
= New ArrayList
        
Catch ex As Exception
            Debug.WriteLine(
"Client_New:" & Err.Description)
        
End Try
    
End Sub

    
'退出服务器的管理
    Public Sub ExitProcess()
        
Try '
            sw.Close()
            sw 
= Nothing
            exitApp()
            ClientSocket.Close()
            mytimer.Dispose()
            ThListen.Abort()
            Debug.WriteLine(
"成功下线!")
        
Catch ex As Exception
            Debug.WriteLine(
"ExitProcess中报错:" & ex.Message)
        
End Try
    
End Sub

    
'一个工作站登陆到服务器
    Private Function Login() As Boolean
        
Try
            receiveDone 
= New ManualResetEvent(False)
            
Dim userBytes As [Byte]()
            
Dim userOK As Boolean = False
            userBytes 
= Encoding.Unicode.GetBytes(LOGININ & username)
            
'向服务器发送客户消息 
            ClientSocket.SendTo(userBytes, ServerEP)
            
Dim data As [Byte]() = New Byte(1024) {}
            
Dim comStr As String = Encoding.Unicode.GetString(data, 04)
            
'异面的接收服务器回送的消息 
            Dim DGrecv As New myMethodDelegate(AddressOf recvLogin)
            DGrecv.BeginInvoke(data, 
NothingNothing)
            
'等待服务器回送消息的时长为10秒,否则为服务器超时 
            receiveDone.WaitOne(500True)
            
Dim recvStr As String = Encoding.Unicode.GetString(data, 04)
            
If recvStr = comStr Then
                Debug.WriteLine(
"服务器超时.登陆失败!!")
                
Return False
            
End If
            
If Encoding.Unicode.GetString(data, 04= LOGINOK Then
                Debug.WriteLine(
"登陆成功!!")
                
Return True
            
Else
                Debug.WriteLine(
"服务器未知错误,登陆失败!!")
                
Return False
            
End If
        
Catch ex As Exception
            Debug.WriteLine(
"Login:" & Err.Description)
        
End Try
    
End Function

    
'解除登陆函数中的线程阻止
    Sub recvLogin(ByRef inData As Byte())

        ClientSocket.Receive(inData)
        receiveDone.Set()

    
End Sub

    
'登出函数 
    Private Sub exitApp()
        
Try
            
Dim loginOutStr As String = LOGINOUT & username
            
Dim sendBytes As [Byte]() = Encoding.Unicode.GetBytes(loginOutStr)
            ClientSocket.SendTo(sendBytes, ServerEP)
        
Catch ex As Exception
            Debug.WriteLine(
"下线失败:" & Err.Description)
        
End Try
    
End Sub

    
'客户程序监听的函数 
    Sub listen()
        
While True
            
Try
                
Dim recv As Integer = 0 '收到的字节数 
                Dim datas As [Byte]() = New Byte(1024) {} '缓冲区大小 
                Dim sender As New IPEndPoint(IPAddress.Any, 0)
                
Dim tempRemoteEP As EndPoint = CType(sender, EndPoint)
                recv 
= ClientSocket.ReceiveFrom(datas, tempRemoteEP)      'data存放接收到的数据,tempRemoteEP存放发送来的ip地址
                Dim tmpdata As New DeclearData(datas, tempRemoteEP, recv)    '装进信息块中
                ReceiveDataList.AddItem(tmpdata)                            '将信息块装进本程序自己的缓冲区
                If Not dealing Then
                    
Dim dealdatathread As New Thread(AddressOf DealData)
                    dealdatathread.Name 
= "dealdata"
                    dealdatathread.Start()
                
End If
            
Catch
                Debug.WriteLine(
"listen:" & Err.Description)
                WriteLog(
"listen:" & Err.Description)
            
End Try
        
End While
    
End Sub

    
'处理不同机器发送过来的信息
    Private Sub DealData()
        
If Not dealing Then
            dealing 
= True
            
Dim tmpmsg As DeclearData
            
While ReceiveDataList.count > 0
                
Try
                    tmpmsg 
= ReceiveDataList.GetFirstItem
                    
Dim msgHead As String = tmpmsg.datastr.Substring(02)
                    
'可以侦听到的命令:
                    Debug.WriteLine("收到:" & tmpmsg.datastr)
                    
If msgHead <> "" Then
                        
Select Case msgHead
                            
Case LOGININ
                                
'如果有一个节点登陆:
                                '暂时不做处理
                            Case GIVEMEDATA         '添加一个接收数据的监视端
                                If Not on_off Then
                                    on_off 
= True       '打开开关
                                    If ThSend Is Nothing Then   '如果此时发送数据的线程没有启动,则启动它
                                        ThSend = New Thread(AddressOf DataMove)
                                        ThSend.Start()
                                        Debug.WriteLine(
"开始发送数据!")
                                    
End If
                                
End If
                                AddRss(tmpmsg.datastr, tmpmsg.fromip)

                            
Case NODATASEND         '取消一个接收数据的监视端
                                RemoveRss(tmpmsg.datastr, tmpmsg.fromip)

                            
Case MSGEND             '控制数据发送成功返回标志
                                msgSendEnd = True
                                sendDone.Set()

                            
Case HOLDOK             '保持在线信息返回
                                testHold = True
                                holdDone.Set()

                            
Case CHTMSGEND          '发送聊天信息返回标志
                                testChat = True
                                chatDone.Set()

                            
Case GETDEVINFO
                                
'要求发送本工作站的基本信息:
                                SendBasicInfo(tmpmsg.fromip)

                            
Case ONEOFF
                                
'某个客户端超时下线:
                                '检验此信息是否为服务器正确端口发送
                                '检测该客户端是否正在接收我们的数据,如果是则终止
                            Case SEARCHCLIENT
                                ReLogin(tmpmsg.fromip)
                            
Case Else

                        
End Select
                    
End If
                
Catch ex As Exception
                    Debug.WriteLine(
"错误的数据:" & tmpmsg.datastr)
                    Debug.WriteLine(
"DealData:" & Err.Description)
                    WriteLog(
"错误的数据:" & tmpmsg.datastr)
                    WriteLog(
"DealData:" & Err.Description)
                
Finally
                    ReceiveDataList.Remove()
                
End Try
            
End While
            dealing 
= False
        
End If
    
End Sub

    
'一个客户端发送请求,要求本工作站向其发送数据,此请求只能由客户端发送
    '向设备实例的SendTO()数组添加该工作站的IP地址(本程序只向固定端口发送数据!)
    Private Function AddRss(ByVal dt As StringByVal ip As IPEndPoint) As Boolean
        
Dim i, j As Integer
        
Dim tmpsetup As ClassSetup
        
Dim flag As Boolean = False
        
Dim success As Boolean = False
        
Dim findsetup As Boolean = False
        
Dim id As String = dt.Substring(2, dt.Length - 2)
        
Try
            
For i = 0 To DataSetUp.count - 1
                tmpsetup 
= DataSetUp.item(i)
                
If id = "" Then
                    flag 
= False
                    
For j = 0 To tmpsetup.SendTo.Length - 1
                        
If (Not tmpsetup.SendTo(j) Is NothingAndAlso tmpsetup.SendTo(j).Address.ToString = ip.Address.ToString Then
                            
'这个设备本来就向该客户端发送数据
                            flag = True
                            
Exit For
                        
End If
                    
Next
                    
If Not flag Then
                        j 
= tmpsetup.SendTo.Length
                        
ReDim Preserve tmpsetup.SendTo(j + 1)
                        tmpsetup.SendTo(j) 
= New IPEndPoint(ip.Address, 5556)
                    
End If
                    success 
= True
                    findsetup 
= True
                
ElseIf tmpsetup.ID = id Then          '正是要申请的设备,进行下一步判断:
                    findsetup = True    '找到了这个设备
                    If tmpsetup.SendTo Is Nothing Then
                        
ReDim Preserve tmpsetup.SendTo(1)
                        tmpsetup.SendTo(
0= New IPEndPoint(ip.Address, 5556)           '第一个申请的客户端
                        success = True
                        
Exit For 'i
                    Else
                        flag 
= False
                        
For j = 0 To tmpsetup.SendTo.Length - 1
                            
If (Not tmpsetup.SendTo(j) Is NothingAndAlso tmpsetup.SendTo(j).Address.ToString = ip.Address.ToString Then   '重复申请
                                Debug.WriteLine("该客户端已经在接收数据了!这是违法操作!")
                                flag 
= True
                                
Exit For    'j
                            End If
                        
Next j
                        
If Not flag Then        '正常的申请数据
                            flag = False        '检查前面是否有空的数组元素可用
                            For j = 0 To tmpsetup.SendTo.Length - 1
                                
If tmpsetup.SendTo(j) Is Nothing Then   '找到可用的
                                    tmpsetup.SendTo(j) = New IPEndPoint(ip.Address, 5556)
                                    success 
= True
                                    flag 
= True
                                    
Exit For
                                
End If
                            
Next j
                            
If Not flag Then    '没有找到可用的,重新扩展数组
                                j = tmpsetup.SendTo.Length
                                
ReDim Preserve tmpsetup.SendTo(j + 1)
                                tmpsetup.SendTo(j) 
= New IPEndPoint(ip.Address, 5556)
                                success 
= True
                            
End If
                        
End If
                        
Exit For    'i
                    End If
                
End If
            
Next i
            
If Not findsetup Then
                Debug.WriteLine(
"没有找到该设备,ID信息错误!")
            
End If
            dt 
= Nothing
            ip 
= Nothing
            tmpsetup 
= Nothing
            flag 
= Nothing
            id 
= Nothing
            
Return success
        
Catch ex As Exception
            Debug.WriteLine(
"AddRss:" & Err.Description)
        
End Try
    
End Function

    
'取消从本工作站获取数据
    '这个消息只由客户端发送
    Private Function RemoveRss(ByVal dt As StringByVal ip As IPEndPoint) As Boolean
        
Dim i, j As Integer
        
Dim tmpsetup As ClassSetup
        
Dim flag As Boolean = False
        
Dim findsetup As Boolean = False
        
Dim id As String = dt.Substring(2, dt.Length - 2'Encoding.Unicode.GetString(dt, 4, recv - 4)
        For i = 0 To DataSetUp.count - 1
            tmpsetup 
= DataSetUp.item(i)
            
If id = "" Then
                
'该客户端下线,取消所有向此客户端的发送:
                If Not tmpsetup.SendTo Is Nothing Then
                    
For j = 0 To tmpsetup.SendTo.Length - 1
                        
If (Not tmpsetup.SendTo(j) Is NothingAndAlso tmpsetup.SendTo(j).Address.ToString = ip.Address.ToString Then
                            
'Debug.WriteLine(tmpsetup.SendTo(j).ToString)
                            tmpsetup.SendTo(j) = Nothing
                            flag 
= True
                            findsetup 
= True
                            
'Exit For
                        End If
                    
Next
                
End If
            
ElseIf tmpsetup.id = id Then      '找到该设备
                findsetup = True
                flag 
= False
                
For j = 0 To tmpsetup.SendTo.Length - 1
                    
If Not tmpsetup.SendTo(j) Is Nothing Then
                        
'Debug.WriteLine(tmpsetup.SendTo(j).ToString & ip.ToString)
                        If tmpsetup.SendTo(j).Address.ToString = ip.Address.ToString Then       '找到了这个客户端地址
                            tmpsetup.SendTo(j) = Nothing
                            flag 
= True
                            
'Exit For    'j
                        End If
                    
End If
                
Next
                
If Not flag Then    '没有找到客户端地址
                    Debug.WriteLine("违法操作,该客户端没有申请过该工作站的数据!")
                
End If
                
Exit For    'i
            End If
        
Next
        
If Not findsetup Then
            Debug.WriteLine(
"没有找到对应的设备!非法操作!")
            
Return False
        
End If
        
If Not flag Then     '没有找到客户端地址
            Debug.WriteLine("没有找到对应的客户端地址!非法操作!")
            
Return False
        
End If
        
'检查当前是否还有客户端在接收数据:
        flag = False
        
For i = 0 To DataSetUp.count - 1
            tmpsetup 
= DataSetUp.item(i)
            
For j = 0 To tmpsetup.SendTo.Length - 1
                
If Not tmpsetup.SendTo(j) Is Nothing Then
                    
'Debug.WriteLine("还有 " & tmpsetup.SendTo(j).ToString & " 在接收数据!")
                    flag = True         '找到一个!
                End If
            
Next
        
Next
        
'Debug.WriteLine("用户:" & ip.ToString & "需要取消接收数据")
        'Debug.WriteLine(flag)
        If Not flag Then
            
'当前已经没有客户端需要本工作站发送数据了,关闭开关
            on_off = False        '关闭发送开关
            Debug.WriteLine("关闭发送开关!")
            ThSend.Abort()
            ThSend 
= Nothing
        
End If
        dt 
= Nothing
        
'recv = Nothing
        ip = Nothing
        i 
= Nothing
        j 
= Nothing
        tmpsetup 
= Nothing
        flag 
= Nothing
        findsetup 
= Nothing
        id 
= Nothing
    
End Function

    
'用保持在线状态的函数 
    Private Sub holdonline(ByVal state As [Object])
        
Try
            ClientSocket.SendTo(Encoding.Unicode.GetBytes(HOLDLINE 
& username), ServerEP)
        
Catch ex As Exception
            Debug.WriteLine(
"holdonline:" & ex.Message)
        
End Try
    
End Sub

    
'用于向各个客户端发送数据,此函数通过Send线程控制:
    '这个函数只用来发送数据信息,即以40开头的信息
    Public Sub DataMove()
        
Try
            
Dim data As String
            
Dim TempSend As String
            
Dim TempDev As ClassSetup
            
Dim i As Integer
            Debug.WriteLine(
"启动发送器:")
            
While on_off
                Application.DoEvents()
                
If SendDataList.Count > 0 Then      '如果发送的链表中有数据,则按照顺序发送:
                    TempDev = CType(SendDataList.Item(0), ClassData).myDevice       '获取是哪个设备要求发送的,空代表是本系统要求发送的,而不是某个设备的数据信息
                    data = CType(SendDataList.Item(0), ClassData).mydata            '获取数据
                    '发送本数据:
                    For i = 0 To TempDev.SendTo.Length - 1
                        
If Not TempDev.SendTo(i) Is Nothing Then                    '向所有需要接收本设备的客户端发送
                            SendLongData(data, TempDev.SendTo(i))
                        
End If
                    
Next
                    
CType(SendDataList.Item(0), ClassData).dispose()                '将信息块释放掉
                    SendDataList.RemoveAt(0)                                        '删除此信息块
                End If
                Thread.Sleep(
100)
            
End While
            data 
= Nothing
            TempSend 
= Nothing
            Debug.WriteLine(
"发送器结束")
        
Catch ex As Exception
            Debug.WriteLine(
"DataMove:" & Err.Description)
        
End Try
    
End Sub

    
'将一整串长数据发送到指定的ip地址:
    '格式:40+标志量+数据
    Private Function SendLongData(ByVal thedata As StringByVal ip As IPEndPoint) As Boolean
        
Try
            
Dim i As Integer
            
Dim head As String = thedata.Substring(02)
            
Dim TempSend As String
            
Dim sendbytes() As Byte
            thedata 
= thedata.Substring(2, thedata.Length - 2)                          '获取除了数据头之外的所有数据
            If thedata.Length > movelenth Then                                          '第一次数据!
                TempSend = head & "0" & thedata.Substring(0, movelenth)                 '添加0,表示数据的开始
                thedata = thedata.Substring(movelenth, thedata.Length - movelenth)      '将发送出去的那些字符除掉
                sendbytes = Encoding.Unicode.GetBytes(TempSend)
                ClientSocket.SendTo(sendbytes, ip)                                      
'发送本段信息
                Thread.Sleep(100)
                
While thedata.Length > movelenth                                        '如果剩下的数据大小大于可以发送的字节数,则拆分
                    '发送:
                    TempSend = head & "2" & thedata.Substring(0, movelenth)             '添加2,表示数据的中间部分
                    thedata = thedata.Substring(movelenth, thedata.Length - movelenth)  '将发送出去的那些字符除掉
                    sendbytes = Encoding.Unicode.GetBytes(TempSend)
                    ClientSocket.SendTo(sendbytes, ip)                                  
'发送本段信息
                    Thread.Sleep(100)
                
End While
                
If thedata.Length > 0 Then                                              '发送最后一段信息
                    TempSend = head & "1" & thedata                                     '添加1,表示是数据的结束
                    sendbytes = Encoding.Unicode.GetBytes(TempSend)
                    ClientSocket.SendTo(sendbytes, ip)
                    Thread.Sleep(
100)
                
End If
            
Else
                TempSend 
= head & "3" & thedata                                         '添加3,表示这里是全部数据一次性传送完毕
                sendbytes = Encoding.Unicode.GetBytes(TempSend)
                ClientSocket.SendTo(sendbytes, ip)                                      
'发送本段信息
            End If
            i 
= Nothing
            head 
= Nothing
            thedata 
= Nothing
            ip 
= Nothing
            TempSend 
= Nothing
            sendbytes 
= Nothing
            
Return True
        
Catch ex As Exception
            Debug.WriteLine(
"SendLongData: " & Err.Description)
            
Return False
        
End Try
    
End Function

    
'获取本地地址:
    Private Function getIdOfLocalhost() As String
        
Try
            
Dim addressList As System.Net.IPAddress() = Dns.GetHostByName(Dns.GetHostName()).AddressList
            
Dim j As Integer           '定义的循环变量j,得到本地机的ip
            For j = 0 To addressList.Length - 1
                
If ServerEP.Address.GetAddressBytes(0= addressList(j).GetAddressBytes(0And ServerEP.Address.GetAddressBytes(1= addressList(j).GetAddressBytes(1And ServerEP.Address.GetAddressBytes(2= addressList(j).GetAddressBytes(2Then
                    
Return addressList(j).ToString()
                
End If
            
Next j
            
Return ""
        
Catch ex As Exception
            Debug.WriteLine(
"getIdOfLocalhost:" & Err.Description)
        
End Try
    
End Function

    
'发送本工作站的基本信息:(本函数执行的时机由接口控制,一旦出现新的设备或配置完成即执行一次)
    '如果需要发送的目标为空,则说明是发送给服务器的
    '不为空,则是发送给某个客户端的
    Public Sub SendBasicInfo(Optional ByVal sendtoEP As IPEndPoint = Nothing)
        
Try
            
Dim tmpstr As String = frmShowArguments.SaveConfig(True)
            
Dim head As String = RECDEVINFO
            
Dim TempSend As String
            
Dim sendBytes() As Byte
            
Dim movelenth As Integer = 509 '最大为511,加上标志位为512,乘以2为传送的最大字节数:1024
            '重新组合配置文件:
            If sendtoEP Is Nothing Then sendtoEP = ServerEP
            
While tmpstr.Length > movelenth                                   '如果数据大小大于可以发送的字节数,则拆分
                '发送:
                TempSend = head & "0" & tmpstr.Substring(0, movelenth)        '添加0,表示数据未结束
                tmpstr = tmpstr.Substring(movelenth, tmpstr.Length - movelenth)
                sendBytes 
= Encoding.Unicode.GetBytes(TempSend)
                ClientSocket.SendTo(sendBytes, sendtoEP)
                Thread.Sleep(
100)
            
End While
            
If tmpstr.Length > 0 Then                                         '发送最后一段信息
                TempSend = head & "1" & tmpstr
                sendBytes 
= Encoding.Unicode.GetBytes(TempSend)
                ClientSocket.SendTo(sendBytes, sendtoEP)
                Thread.Sleep(
100)
            
End If
            Debug.WriteLine(
"" & sendtoEP.ToString & "发送配置信息")
            tmpstr 
= Nothing
            head 
= Nothing
            TempSend 
= Nothing
            sendBytes 
= Nothing
            sendtoEP 
= Nothing
            movelenth 
= Nothing
        
Catch ex As Exception
            Debug.WriteLine(
"SendBasicInfo:" & Err.Description)
        
End Try
    
End Sub

    
'用于回应服务器服务程序发送的探测信息
    '只是一个回应,不对服务器发回的确认成功信息做任何处理
    Private Sub ReLogin(ByVal TheServerEP As IPEndPoint)
        
Try
            
Dim userBytes As [Byte]()
            userBytes 
= Encoding.Unicode.GetBytes(LOGININ & username)
            
'向服务器发送客户消息 
            ClientSocket.SendTo(userBytes, TheServerEP)
        
Catch ex As Exception
            Debug.WriteLine(
"ReLogin:" & Err.Description)
        
End Try
    
End Sub

    
Sub WriteLog(ByVal msg As String)
        Debug.WriteLine(msg)
        sw.WriteLine(msg)
        sw.Flush()
    
End Sub

#End Region

End Class


注:DeclearData和DataQueue两个类参见上一篇文章:.net中的socket异步通信实现--服务器端代码

posted on 2008-07-10 17:09  杨斌_曹悦_饶龙_田强  阅读(4732)  评论(9编辑  收藏  举报