02/10/2018, 00:07

Viết ứng dụng chia sẽ Camera trong mạng LAN sử dụng giao thức UDP

Viết ứng dụng chia sẽ Camera trong mạng LAN sử dụng giao thức UDP, trong bài viết này mình sử dụng thư viện Touchlesslib, để sử dụng camera của laptop. Và sử dụng giao thức UDP để chuyển video sang máy tính nội bộ trong mạng LAN. Quy trình chuyển ...

Viết ứng dụng chia sẽ Camera trong mạng LAN sử dụng giao thức UDP, trong bài viết này mình sử dụng thư viện Touchlesslib, để sử dụng camera của laptop. Và sử dụng giao thức UDP để chuyển video sang máy tính nội bộ trong mạng LAN.

Quy trình chuyển Camera qua mạng.

Sử dụng thư viện Lib Touchless sau đó, convert hình ảnh sang dạng byte và truyền sang máy tính nhận, Khi máy tính nhận được dữ liệu sẽ chuyển ngược lại byte sang hình ảnh để hiện thị lên form

Dưới đây là video hướng dẫn và demo:

I. Giới thiệu giao thức UDP:

UDP là giao thức không liên kết, cung cấp dịch vụ giao vận (Transport Layer) không tin cậy được, sử dụng thay thế cho TCP trong tầng giao vận . Khác với TCP, UDP không có chức năng thiết lập và giải phóng liên kết, không có cơ chế báo nhận (ACK), không sắp xếp tuần tự các đơn vị dữ liệu (datagram) đến và có thể dẫn đến tình trạng mất hoặc trùng dữ liệu mà không hề có thông báo lỗi cho người gửi.

TCP và UDP là  2 giao thức ở tầng giao vận và cùng sử dụng giao thức IP trong tầng mạng. Nhưng không giống như UDP, TCP cung cấp dịch vụ liên kết tin cậy và có liên kết.
Có liên kết ở đây có nghĩa là 2 ứng dụng sử dụng TCP  phải thiết lập liên kết với nhau trước khi trao đổi dữ liệu. Sự tin cậy trong dịch vụ được cung cấp bởi TCP được thể hiện như sau:
− Dữ liệu từ tầng ứng dụng gửi đến được được TCP chia thành các segment có kích thước phù hợp nhất để truyền đi .
− Khi TCP gửi  1 segment, nó duy trì một thời lượng để chờ phúc đáp từ trạm nhận. Nếu trong khoảng thời gian đó phúc đáp không tới được trạm gửi thì segment đó được truyền lại.
− Khi TCP trên trạm nhận nhận dữ liệu từ trạm gửi nó sẽ gửi tới trạm gửi 1 phúc đáp tuy nhiên phúc đáp không được gửi lại ngay lập tức mà thường trễ một khoảng thời gian .
− TCP duy trì giá trị tổng kiểm tra (checksum) trong phần Header của dữ liệu để nhận ra bất kỳ sự thay đổi nào trong quá trình truyền dẫn. Nếu 1 segment bị lỗi thì TCP ở phía trạm nhận sẽ loại bỏ và không phúc đáp lại để trạm gửi truyền lại segment bị lỗi đó. 
Giống như IP datagram, TCP segment có thể tới đích một cách không tuần tự. Do vậy TCP ở trạm nhận sẽ sắp xếp lại dữ liệu và sau đó gửi lên tầng ứng dụng đảm bảo tính đúng đắn của dữ liệu. Khi IP datagram  bị trùng lặp TCP tại trạm nhận sẽ loại bỏ dữ liệu trùng lặp đó .
TCP cũng cung cấp khả năng điều khiển luồng. Mỗi đầu của liên kết TCP có vùng đệm (buffer) giới hạn do đó TCP tại trạm nhận chỉ cho phép trạm gửi truyền một lượng dữ liệu nhất định (nhỏ hơn không gian buffer còn lại). Điều này tránh xảy ra trường hợp trạm có tốc độ cao chiếm toàn bộ vùng đệm của trạm có tốc độ chậm hơn.

- Đầu tiên, các bạn cần tải thư viện Touchlesslib về gồm 2 file dll: TouchlessLib.dll và WebCamLib.dll.

Sau đây ta tiến hành code: 

Import thư viện Touchless và thư mục cần thiết vào.

Imports System.Net.Sockets
Imports System.Threading
Imports TouchlessLib

Khai báo các biến sử dụng camera và kích thước hiện thị camera

Dim subscriber As New UdpClient()
Dim publisher As New UdpClient()
Dim mycomputername As String = Environment.MachineName
Dim mycomputerIP() As System.Net.IPAddress = System.Net.Dns.GetHostAddresses(mycomputername)


Dim Touchless As New TouchlessLib.TouchlessMgr
Dim Camera1 As TouchlessLib.Camera = Touchless.Cameras.ElementAt(0)
Dim picsize As Size = New Size(160, 120)

Viết sự kiện cho form load

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        publisher.Client.Blocking = False
        subscriber.Client.ReceiveTimeout = 100
        subscriber.Client.Blocking = False
        subscriber.ExclusiveAddressUse = False
        publisher.ExclusiveAddressUse = False
        TB_Host.Text = Environment.MachineName

        Label3.Text = "My Name: " & Environment.MachineName

        Touchless.CurrentCamera = Camera1
        Touchless.CurrentCamera.CaptureWidth = picsize.Width
        Touchless.CurrentCamera.CaptureHeight = picsize.Height
End Sub

Viết hàm convert byte sang image và image sang byte khi timer tick

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        'Gởi
        Try

            Dim bitmapz As Bitmap = New Bitmap(picsize.Width, picsize.Height)
            bitmapz = Touchless.CurrentCamera.GetCurrentImage
            PictureBox1.Image = bitmapz

            Dim sendbytes() As Byte
            bytesfromimage(sendbytes, bitmapz)

            publisher.Send(sendbytes, sendbytes.Length)
        Catch ex As Exception
        End Try

        'Nhận
        Try

            Dim ep As System.Net.IPEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0)
            Dim rcvbytes() As Byte = subscriber.Receive(ep)
            Dim bitmapz As Bitmap = New Bitmap(picsize.Width, picsize.Height)
            imagefrombytes(rcvbytes, bitmapz)
            PictureBox2.Image = bitmapz

        Catch ex As Exception
        End Try

End Sub

+ Hàm convet Image sang Byte

Private Sub imagefrombytes(ByRef bytez() As Byte, ByRef piccolor As Bitmap)
        Dim rect As New Rectangle(0, 0, piccolor.Width, piccolor.Height)
        Dim bmpData As System.Drawing.Imaging.BitmapData = piccolor.LockBits(rect, _
            Drawing.Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format32bppRgb)
        Dim ptr As IntPtr = bmpData.Scan0
        Dim bytes As Integer = bmpData.Stride * piccolor.Height
        Dim rgbValues(bytes - 1) As Byte
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)

        Dim secondcounter As Integer
        Dim tempred As Integer
        Dim tempblue As Integer
        Dim tempgreen As Integer
        Dim tempalpha As Integer
        secondcounter = 0

        While secondcounter < rgbValues.Length
            tempblue = rgbValues(secondcounter)
            tempgreen = rgbValues(secondcounter + 1)
            tempred = rgbValues(secondcounter + 2)
            tempalpha = rgbValues(secondcounter + 3)
            tempalpha = 255

            tempred = bytez(((secondcounter * 0.25) * 3) + 0)
            tempgreen = bytez(((secondcounter * 0.25) * 3) + 1)
            tempblue = bytez(((secondcounter * 0.25) * 3) + 2)

            rgbValues(secondcounter) = tempblue
            rgbValues(secondcounter + 1) = tempgreen
            rgbValues(secondcounter + 2) = tempred
            rgbValues(secondcounter + 3) = tempalpha

            secondcounter = secondcounter + 4
        End While


        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)

        piccolor.UnlockBits(bmpData)

End Sub

+ Hàm convert byte sang Image

Private Sub bytesfromimage(ByRef bytez() As Byte, ByRef piccolor As Bitmap)
        Dim rect As New Rectangle(0, 0, piccolor.Width, piccolor.Height)
        Dim bmpData As System.Drawing.Imaging.BitmapData = piccolor.LockBits(rect, _
            Drawing.Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format32bppRgb)
        Dim ptr As IntPtr = bmpData.Scan0
        Dim bytes As Integer = bmpData.Stride * piccolor.Height
        Dim rgbValues(bytes - 1) As Byte
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)

        Dim secondcounter As Integer
        Dim tempred As Integer
        Dim tempblue As Integer
        Dim tempgreen As Integer
        Dim tempalpha As Integer
        secondcounter = 0
        Dim bytelist As List(Of Byte) = New List(Of Byte)

        While secondcounter < rgbValues.Length
            tempblue = rgbValues(secondcounter)
            tempgreen = rgbValues(secondcounter + 1)
            tempred = rgbValues(secondcounter + 2)
            tempalpha = rgbValues(secondcounter + 3)
            tempalpha = 255

            bytelist.Add(tempred)
            bytelist.Add(tempgreen)
            bytelist.Add(tempblue)

            rgbValues(secondcounter) = tempblue
            rgbValues(secondcounter + 1) = tempgreen
            rgbValues(secondcounter + 2) = tempred
            rgbValues(secondcounter + 3) = tempalpha

            secondcounter = secondcounter + 4
        End While


        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)

        piccolor.UnlockBits(bmpData)

        Dim bytearray(bytelist.Count - 1) As Byte
        For i = 0 To bytelist.Count - 1
            bytearray(i) = bytelist(i)
        Next
        bytez = bytearray

End Sub

- Viết sự kiện cho nút gởi camera

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        publisher.Connect(TB_Host.Text, 2013)
        subscriber.Client.Bind(New Net.IPEndPoint(Net.IPAddress.Any, 2013))
End Sub

Cám ơn các bạn đã xem bài viết. Hãy like and share giúp mình nha các bạn.

Các bạn có thể Đăng ký kênh Youtube của mình ở góc phải bên trên màn hình.

Mọi thắc mắc về bài viết các bạn có thể hỏi ở http://hoidap.laptrinhvb.net để được support.

Download source code

Tags: lập trình socketcamera
0