青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Prayer

在一般中尋求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

作者:楊泉波

引言

    在筆者參與的四川省重點(diǎn)污染源企業(yè)環(huán)境遠(yuǎn)程監(jiān)控系統(tǒng)中,有一項(xiàng)非常重要的工作:將多達(dá)80臺(tái)的遠(yuǎn)程DVS(視頻服務(wù)器)的監(jiān)測(cè)數(shù)據(jù)通過因特網(wǎng)傳輸,由上位機(jī)收集上來,寫入SQL Server 2005數(shù)據(jù)庫中。遠(yuǎn)程數(shù)據(jù)每隔一分鐘發(fā)送一次實(shí)時(shí)數(shù)據(jù)。如果數(shù)據(jù)在一分鐘內(nèi)傳送不成功,那么DVS將認(rèn)為網(wǎng)絡(luò)已經(jīng)斷開,又要不斷的發(fā)起新的連接。因此,上位機(jī)能不能及時(shí)的準(zhǔn)確的收集、寫入,是系統(tǒng)成敗的關(guān)鍵。

項(xiàng)目分析

    80多臺(tái)遠(yuǎn)程DVS正在不間斷的采集數(shù)據(jù),在網(wǎng)絡(luò)正常的情況下,會(huì)不間斷的向上位機(jī)發(fā)送數(shù)據(jù)。如果采用傳統(tǒng)的單線程結(jié)構(gòu),上位機(jī)接受連接請(qǐng)求,接收處理數(shù)據(jù),將數(shù)據(jù)寫入數(shù)據(jù)庫,然后再接受新的連接請(qǐng)求,接收處理數(shù)據(jù),……,這樣,上位機(jī)程序異常繁忙,CPU利用率幾乎將達(dá)100%。由于服務(wù)器不能迅速處理請(qǐng)求,DVS只好等待。
    更為重要的是,為了減少上位機(jī)發(fā)送響應(yīng)連接的次數(shù),設(shè)備采用的是長(zhǎng)連接,即發(fā)送一次連接請(qǐng)求并得到響應(yīng)后,發(fā)送數(shù)據(jù)時(shí)不再發(fā)送連接請(qǐng)求。因此,要求上位機(jī)能夠保存客戶端的Socket。
為了避免這種情形發(fā)生。筆者采用了異步、多線程來處理。所謂異步,是程序調(diào)用一個(gè)方法后立即返回,總體而言,主線程與方法線程并行執(zhí)行。而同步即程序執(zhí)行一個(gè)方法,等該方法返回之后,繼續(xù)往下走,本系統(tǒng)從功能上分成3個(gè)模塊,即3個(gè)前后關(guān)聯(lián)的線程:主線程、數(shù)據(jù)接收線程、存入數(shù)據(jù)庫線程,它們異步執(zhí)行。

主線程

    主線程工作流程如圖一所示。其主要功能是:初始化參數(shù),如連接端口號(hào)、IP地址等,偵聽連接請(qǐng)求,將傳入的連接保留到TcpClient對(duì)象數(shù)組sockets,而這個(gè)數(shù)組sockets恰恰是我們后面線程中要用到的全局變量。 為了不使線程間爭(zhēng)用這個(gè)數(shù)組變量,這里用到了VB.net提供的Monitor類,它提供同步對(duì)象的訪問的機(jī)制。
    當(dāng)主線程偵聽到遠(yuǎn)程DVS有連接請(qǐng)求時(shí),立即執(zhí)行AcceptTcpClient方法,創(chuàng)建一個(gè)TcpClient實(shí)例,并將它放入sockets數(shù)組。同時(shí)創(chuàng)建線程對(duì)象serverthread。
聲明創(chuàng)建線程時(shí),使用 ThreadStart 委托作為其唯一參數(shù)的構(gòu)造函數(shù)創(chuàng)建 Thread 類的新實(shí)例,創(chuàng)建線程時(shí)需要傳遞處理連接的過程或函數(shù)的地址以被線程調(diào)用。創(chuàng)建線程委托,傳遞需要操作的過程的地址,這部分的代碼如下所示:
Public Sub WaitData()
        Try
            Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())
            Dim localAddr As IPAddress = ipHostInfo.AddressList(0)
            s = New TcpListener(localAddr, ListenPort)
            s.Start()’開始偵聽連接請(qǐng)求
            Dim Recdatathread As New Thread(New ThreadStart(AddressOf RecDataProc)) ’創(chuàng)建數(shù)據(jù)接收線程
            Recdatathread.IsBackground = True
            Recdatathread.Start()’啟動(dòng)線程
            While True
                Dim client As TcpClient = s.AcceptTcpClient()
                Monitor.Enter(sockets) '在指定對(duì)象上獲取排他鎖
                sockets(socketcount) = client
                socketcount = socketcount + 1
                Monitor.Exit(sockets) '釋放指定對(duì)象上的排他鎖                 
            End While
        Catch e As SocketException
            s.Stop()
            saveErrLog(Date.Now, CType(s.AcceptTcpClient.Client.RemoteEndPoint, IPEndPoint).Address.ToString(), e.Message)’寫入錯(cuò)誤日志
        Catch e As ThreadAbortException
            t.Abort()
            saveErrLog(Date.Now, CType(s.AcceptTcpClient.Client.RemoteEndPoint, IPEndPoint).Address.ToString(), e.Message) ’寫入錯(cuò)誤日志
        Finally
            t.Abort()
            End
        End Try
End Sub

數(shù)據(jù)接收線程

    數(shù)據(jù)接收線程的工作流程如圖二所示。主要功能是:將掛起連接的DVS上傳數(shù)據(jù)從流中讀取出來,創(chuàng)建數(shù)據(jù)寫入線程,并在listbox中顯示。
從保存的socket數(shù)組中讀取字節(jié)流時(shí),必須考慮以下問題:
一、有些DVS可能會(huì)在工作一段時(shí)間后發(fā)生設(shè)備故障或者網(wǎng)絡(luò)中斷,但服務(wù)器保存的是其歷史socket,因此,必須判斷其connect屬性,即設(shè)備是否在線。
二、為了減少服務(wù)器的空等時(shí)間,必須判斷流對(duì)象(stream)的DataAvailable屬性。
三、創(chuàng)建線程saveToDb時(shí),必須考慮傳入?yún)?shù)的問題。通常的線程創(chuàng)建是不可提供參數(shù)的。我們將線程saveToDb的執(zhí)行體封裝到一個(gè)類中,通過初始化類的成員變量的方法,來達(dá)到傳送參數(shù)的目的。
四、由于本線程是長(zhǎng)駐內(nèi)存并循環(huán)執(zhí)行的。因此,應(yīng)當(dāng)在適當(dāng)?shù)牡胤阶柚梗駝t,CPU的利用率將達(dá)幾乎100%。
這部分的代碼如下:
Public Sub RecDataProc()
        Dim i As Integer
        Dim c As TcpClient
        While (True)
            Try
                For i = 0 To socketList.Count - 1
          If socketList.Item(i).client.connected Then '如果該連接在線
             Dim dh1 As DelegateHandler = New DelegateHandler(AddressOf displayStatusBarPanel2)
'New 出一個(gè)委托并指定委托方法
                      Me.Invoke(dh1, New Object() {CStr(i)})  '調(diào)用invoke方法
                      c = socketList.Item(i)
                      Dim stream As NetworkStream = c.GetStream()
                      If stream.DataAvailable Then
                      Dim dh As DelegateHandler1 = New DelegateHandler1(AddressOf ShowInBox)
                      Dim readbuff As New ReadBuffClass(c, stream, Connection, dh) '由構(gòu)造函數(shù)來初始化成員變量
                      ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf readbuff.ReadBuff), readbuff)’把具體從流中讀取數(shù)據(jù)的工作交給線程池的線程來進(jìn)行
                       Dim workerThreads, portThreads As Integer
                       ThreadPool.GetAvailableThreads(workerThreads, portThreads)
                       Dim dh2 As DelegateHandler = New DelegateHandler(AddressOf displayStatusBarPanel4)
'New 出一個(gè)委托并指定委托方法
                       Me.Invoke(dh2, New Object() {workerThreads.ToString})  '調(diào)用invoke方法
                    End If
                       Thread.Sleep(20) '如果不阻止,則CPU利用率將為100%
                    End If
                Next
             Catch ex As System.ArgumentOutOfRangeException
             Catch ex As System.InvalidOperationException
             Catch ex As ObjectDisposedException 'TcpClient 已關(guān)閉
             Catch ex As SocketException
             Catch ex As ThreadAbortException
             Catch ex As System.IO.IOException              
             Catch ex As System.AccessViolationException
             Finally
            End Try
        End While
End Sub

數(shù)據(jù)處理線程

    這部份線程每個(gè)都由線程池來調(diào)度運(yùn)行。由于要接收線程參數(shù),因此,線程本身被封裝到一個(gè)類中,限于篇幅的原因,只描述類的結(jié)構(gòu)。
Public Class ReadBuffClass
    Private sck As TcpClient
    Private ns As NetworkStream
    Private sqlcnn As SqlConnection
    Private delg As frmServerMain.DelegateHandler1
 
    Dim sqlcmd As SqlCommand
Dim sqlda As SqlDataAdapter
 
Public Sub New(ByVal sc As TcpClient, ByVal n As NetworkStream, ByVal cn As SqlConnection, ByVal dh As frmServerMain.DelegateHandler1) '由構(gòu)造函數(shù)來初始化成員變量
        Me.sck = sc
        Me.ns = n
        Me.sqlcnn = cn
       Me.delg = dh
End Sub
 
Public Sub ReadBuff(ByVal state As Object) ' 線程的入口函數(shù)
        Dim datastring As String = ""
        ns.ReadTimeout = 100 '讀取失敗前經(jīng)歷的毫秒數(shù)
        Try
            While (True)
                Dim bytes(2048) As Byte
                ns.Read(bytes, 0, 2048)
                datastring = datastring + Encoding.ASCII.GetString(bytes)
                If datastring.IndexOf(vbCrLf) > 0 Then
                    Exit While
                End If
            End While
            delg.Invoke(datastring, sck) '通過委托的方式,將參數(shù)傳給UI
            Dim tmparr() As String = datastring.Split("##")
            Dim i As Integer
            For i = 0 To tmparr.Length - 1
                If tmparr(i) <> "" Then
                    ProcessInfo(tmparr(i))
                End If
            Next
        Catch ex As System.AccessViolationException
        Catch ex As NotSupportedException
       Catch ex As ArgumentNullException
       Catch ex As ArgumentOutOfRangeException
       Catch ex As ObjectDisposedException
Catch ex As IO.IOException '
       Catch ex As SocketException
       Catch ex As ThreadAbortException
      Finally
   End Try
End Sub
 
Private Sub ProcessInfo(ByVal tmpString As String) '對(duì)收到的數(shù)據(jù)進(jìn)行解析、處理
……
End Sub
……
End Class

結(jié)束語

    本文著重論述的是在VB2005的環(huán)境下,運(yùn)用多線程異步實(shí)現(xiàn)遠(yuǎn)程DVS數(shù)據(jù)收集的原理,重點(diǎn)考慮的是怎樣提高程序的反應(yīng)速度,特別討論了程序開發(fā)中的一些細(xì)節(jié)問題,對(duì)有志于從事遠(yuǎn)程臨控系統(tǒng)開發(fā)的軟件人員有一定的參考意義。
文中代碼在windows2003+VB2005+SqlServer2005的環(huán)境下調(diào)試通過,現(xiàn)在正在使用。

Feedback

# re: 在vb.net中運(yùn)用多線程實(shí)現(xiàn)遠(yuǎn)程數(shù)據(jù)收集  回復(fù)  更多評(píng)論   

2009-05-11 17:11 by anndy
看來博主是socket方面的編程的專家了,請(qǐng)問下“在vb.net中運(yùn)用多線程實(shí)現(xiàn)遠(yuǎn)程數(shù)據(jù)收集”,是你的原創(chuàng)嗎
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久亚洲春色中文字幕| 欧美性淫爽ww久久久久无| 在线亚洲激情| 国产日韩精品一区二区三区| 欧美主播一区二区三区美女 久久精品人| 快射av在线播放一区| 亚洲图色在线| 亚洲精品三级| 91久久久久久国产精品| 亚洲在线中文字幕| 亚洲精品一区二区网址 | 蜜桃久久精品乱码一区二区| 在线一区免费观看| 亚洲精品午夜| 亚洲素人在线| 亚洲在线免费观看| 久久激情网站| 亚洲精品一区二| 久久午夜视频| 亚洲第一主播视频| 欧美母乳在线| 欧美日韩高清一区| 欧美午夜电影在线| 国产免费一区二区三区香蕉精| 国产精品99一区二区| 国产在线精品自拍| av72成人在线| 噜噜噜噜噜久久久久久91| 欧美波霸影院| 亚洲一区中文字幕在线观看| 欧美在线视频播放| 欧美日韩国产影院| 国产综合色一区二区三区| 99热在线精品观看| 久久免费视频在线| 国产精品美女一区二区| 在线日韩视频| 久久久国产91| 午夜在线精品| 欧美日韩一区二区视频在线观看 | 欧美一区二区三区在线| 亚洲一区二区三区在线看| 久久偷窥视频| 亚洲一二三级电影| 欧美视频精品在线| 亚洲国产婷婷香蕉久久久久久99| 亚洲视频大全| 欧美成人国产| 一区二区三区精品在线| 国产精品午夜在线| 国产亚洲激情在线| 亚洲精品在线观| 亚洲精品乱码| 亚洲先锋成人| 欧美成人国产va精品日本一级| 欧美另类视频| 在线精品亚洲一区二区| 久久超碰97人人做人人爱| 欧美一区二区在线免费观看| 裸体一区二区| 亚洲自拍电影| 国产精品一区二区欧美| 欧美高清一区二区| 亚洲欧美日韩国产成人| 国产精品久久午夜| 夜夜嗨av色综合久久久综合网| 久久免费高清视频| 亚洲欧美日韩一区二区三区在线观看 | 亚洲福利一区| 亚洲自拍另类| 亚洲人屁股眼子交8| 久久综合伊人77777蜜臀| 国产一区99| 久久久久国产精品一区三寸 | 亚洲乱码国产乱码精品精可以看| 欧美日韩综合另类| 国产精品普通话对白| 亚洲一级在线观看| 久久天天狠狠| 欧美一区二区日韩| 日韩小视频在线观看| 亚洲综合色噜噜狠狠| 欧美成人自拍视频| 久久国产主播精品| 午夜精品福利一区二区三区av| 亚洲午夜视频在线| 亚洲一区二区在线看| 欧美日韩第一区日日骚| 欧美成人69| 狠狠色丁香久久综合频道| 亚洲高清123| 午夜精品一区二区三区电影天堂| 美女精品在线| 麻豆国产精品777777在线| 在线观看成人av| 免费不卡欧美自拍视频| 欧美成人精品h版在线观看| 午夜亚洲影视| 亚洲经典在线看| 久久综合激情| 91久久极品少妇xxxxⅹ软件| 亚洲永久字幕| 国产日韩欧美不卡在线| 欧美影片第一页| 午夜精品网站| 9l国产精品久久久久麻豆| 欧美日韩亚洲一区二区三区四区 | 一区二区三区偷拍| 亚洲午夜日本在线观看| 欧美日韩精品免费| 一区二区三区高清在线观看| 亚洲国产精品专区久久| 欧美激情视频一区二区三区不卡| 欧美福利在线| 99这里只有精品| 欧美日韩一区二区三区在线| 久久人人爽人人爽爽久久| 欧美国产91| 午夜精品成人在线视频| 一区二区三区在线视频观看| 欧美日韩情趣电影| 亚洲综合电影一区二区三区| 久久亚洲私人国产精品va| 亚洲一区在线播放| 亚洲一区3d动漫同人无遮挡| 亚洲精品乱码久久久久久日本蜜臀 | 99视频精品免费观看| 男女视频一区二区| 亚洲婷婷在线| 久久综合九色综合欧美就去吻| 亚洲美女av网站| 国产日韩在线不卡| 欧美精品18+| 欧美成人一区二区三区片免费| 夜夜嗨av一区二区三区网页| 欧美一区二区三区视频免费| 亚洲欧美日产图| 亚洲免费伊人电影在线观看av| 在线免费观看日本一区| 伊人久久成人| 一区二区三区高清在线观看| 欧美国产精品久久| 久久久久久久999精品视频| 欧美在线视频全部完| 亚洲免费成人av| 一区二区精品在线| 日韩亚洲精品电影| 一本一道久久综合狠狠老精东影业 | 亚洲欧美电影在线观看| 亚洲青色在线| 欧美韩国日本一区| 欧美激情91| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 欧美xx69| 在线精品亚洲一区二区| 国产精品视频精品| 欧美午夜久久久| 国产精品久久久久久久免费软件 | 久久噜噜亚洲综合| 亚洲一区二区三区四区五区午夜| 国产精品最新自拍| 欧美精品久久久久久久| 香蕉乱码成人久久天堂爱免费| 国产精品第一页第二页第三页| 久久爱www.| 亚洲精品裸体| 亚洲国产欧美不卡在线观看| 欧美日韩性视频在线| 性18欧美另类| 在线一区二区三区四区五区| 欧美激情一区二区三区蜜桃视频 | 亚洲女人天堂成人av在线| 亚洲精品一区二| 欧美成人精品在线观看| 亚洲欧美日韩精品| 亚洲最新视频在线| 免费久久99精品国产自| 欧美一激情一区二区三区| 亚洲国产日韩欧美在线图片| 国产欧美精品日韩精品| 国产精品初高中精品久久| 欧美色大人视频| 亚洲理伦在线| 久久av红桃一区二区小说| 一本综合精品| 午夜在线观看免费一区| 欧美1区2区3区| 女人色偷偷aa久久天堂| 亚洲精品一区二区三区av| 99re66热这里只有精品3直播| 蜜桃av综合| 亚洲欧洲日本国产| 国产深夜精品| 免费看亚洲片| 欧美国产日韩一区二区| 欧美黄色大片网站| 亚洲日本va午夜在线电影| 亚洲激情成人网| 欧美96在线丨欧| 亚洲三级影院|