Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 通过套接字共享屏幕_Vb.net_Sockets_Tcp_Screenshot_Networkstream - Fatal编程技术网

Vb.net 通过套接字共享屏幕

Vb.net 通过套接字共享屏幕,vb.net,sockets,tcp,screenshot,networkstream,Vb.net,Sockets,Tcp,Screenshot,Networkstream,我正在VB.NET中制作我的第一个屏幕共享应用程序,使用套接字建立连接 这是从服务器接收屏幕图像的客户端(它们都在线程中运行): 这是服务器端: Private Sub screen() Using imgstream As NetworkStream = imgclient.GetStream() Using ms As New MemoryStream Do Thread.Sleep(34) 'about 30

我正在VB.NET中制作我的第一个屏幕共享应用程序,使用套接字建立连接

这是从服务器接收屏幕图像的客户端(它们都在线程中运行):

这是服务器端:

Private Sub screen()
    Using imgstream As NetworkStream = imgclient.GetStream()
        Using ms As New MemoryStream
            Do
                Thread.Sleep(34) 'about 30 FPS
                ms.Seek(0, SeekOrigin.Begin)
                Using img = ScreenCap()
                    img.Save(ms, Imaging.ImageFormat.Jpeg)
                End Using
                ms.WriteTo(imgstream)
            Loop
        End Using
    End Using
End Sub

Public Function ScreenCap() As Image
    Dim screenSize As Size = New Size(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
    Dim screenGrab As New Bitmap(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height) ', Imaging.PixelFormat.Format16bppRgb555)
    Dim g As Graphics = Graphics.FromImage(screenGrab)
    g.CopyFromScreen(New Point(0, 0), New Point(0, 0), screenSize)
    g.Dispose()
    Return screenGrab
End Function
主要的问题是,当我调用“Image.FromStream(ms)”函数时,它有时会工作,而另一些则不工作,这取决于我设置线程等待的毫秒数。在我的局域网内的两台不同的计算机上进行测试,大约1秒的时间看起来还可以,但CPU网络使用率始终很高。如示例所示,如果我设置为34毫秒左右以获得更多的“活动”,则该函数会因为MemoryStream而引发异常。我怎样才能加快速度?我现在错过了什么更聪明的方法吗?我还尝试在MemoryStream的和处放置一个分隔符字节(如char=“*”),然后将其发送给客户机,客户机每次读取一个字节,直到找到一个与分隔符相等的字符。但事实证明这是一个糟糕的解决方案,因为如果转换为字符,图像的单个字节可能表示分隔符。我的另一个问题是:如何更改图像质量和颜色深度?使用评论中所说的“Imaging.PixelFormat.Format16bppRgb555”是一种好方法吗


谢谢大家!

我不知道你得到了什么例外,但我很确定这与不完整的图像有关。您从未声明过,但很明显您正在使用TCP。TCP的黄金法则是它不处理数据包。您接收的数据是流式传输的,因此不太可能在一次
Read()
调用中接收所有数据。您接收的数据太多或太少。您需要一个指示数据开始和结束的自定义协议。正如您所说,分隔符在处理非纯文本文件时不起作用。相反,您应该实现长度前缀(也称为消息帧)。长度前缀在您发送的数据前面加上数据的长度,因此接收方可以读取数据的大小,并知道在收到一个“数据包”之前应该读取多少数据。在我的回答中,我已经描述了长度前缀:记住一个
NetworkStream.Read()
调用也不能确定读取您请求的所有字节,它只读取当时可用的字节。因此,您必须检查
Read()
的返回值,以确定每次调用时实际读取了多少。用它来记录你收到了多少数据。
Private Sub screen()
    Using imgstream As NetworkStream = imgclient.GetStream()
        Using ms As New MemoryStream
            Do
                Thread.Sleep(34) 'about 30 FPS
                ms.Seek(0, SeekOrigin.Begin)
                Using img = ScreenCap()
                    img.Save(ms, Imaging.ImageFormat.Jpeg)
                End Using
                ms.WriteTo(imgstream)
            Loop
        End Using
    End Using
End Sub

Public Function ScreenCap() As Image
    Dim screenSize As Size = New Size(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
    Dim screenGrab As New Bitmap(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height) ', Imaging.PixelFormat.Format16bppRgb555)
    Dim g As Graphics = Graphics.FromImage(screenGrab)
    g.CopyFromScreen(New Point(0, 0), New Point(0, 0), screenSize)
    g.Dispose()
    Return screenGrab
End Function