通过套接字发送视频帧

7

我使用Kinect设备捕获了视频流。我需要将这些流发送到网络上。为此,我使用了socket。 以下是服务器和客户端的部分代码:

private System.Drawing.Bitmap _CurrentBitmap;
    public ManWindow()
    {
        InitializeComponent();

        this.Loaded += delegate
        {
            BackgroundWorker bw1 = new BackgroundWorker();
            bw1.RunWorkerCompleted += (a, b) => bw1.RunWorkerAsync();
            bw1.DoWork += delegate { SendImage(); };
            bw1.RunWorkerAsync();
        };
    }
    public void SendImage()
    {
        Socket sListen = new Socket(AddressFamily.InterNetwork,
                                    SocketType.Stream,
                                    ProtocolType.Tcp);

        IPAddress IP = IPAddress.Parse("127.0.0.1");
        IPEndPoint IPE = new IPEndPoint(IP, 4321);

        sListen.Bind(IPE);
        sListen.Listen(2);

        while (true)
        {
            Socket clientSocket;
            clientSocket = sListen.Accept();

            var converter = new System.Drawing.ImageConverter();
            byte[] buffer = (byte[])converter.ConvertTo(_CurrentBitmap, typeof(byte[]));
            clientSocket.Send(buffer, buffer.Length, SocketFlags.None);
        }
    }

客户:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        BackgroundWorker bw11111 = new BackgroundWorker();
        bw11111.RunWorkerCompleted += (a, b) => bw11111.RunWorkerAsync();
        bw11111.DoWork += delegate { Recive(); };
        bw11111.RunWorkerAsync();
        Recive();
    }

    public void Recive()
    {
        Socket s = new Socket(AddressFamily.InterNetwork,
                            SocketType.Stream,
                            ProtocolType.Tcp);

        IPAddress IP = IPAddress.Parse("127.0.0.1");
        IPEndPoint IPE = new IPEndPoint(IP, 4321);
        s.Connect(IPE);

        while (true)
        {

            byte[] buffer = new byte[1000000];

            s.Receive(buffer, buffer.Length, SocketFlags.None);

            MemoryStream ms = new MemoryStream(buffer);

            ms.Write(buffer, 0, buffer.Length);
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(ms);

            Dispatcher.BeginInvoke(new Action(() =>
            {
                rgbImage11.Source = bitmap.ToBitmapSource();
            }));

        }
    }

_CurrentBitmap是从Kinect读取并每秒更新的帧。当客户端启动时,调用Socket Receive方法,它接收帧并将其转换为位图,然后将其分配给Image WPF控件。我的问题是这个操作只发生一次并且在客户端中不重复。


只是猜测,但一旦您将图像发送到服务器,您的Socket就会超出范围,因此我想客户端会失去连接并死机。 - Chris
没有出现任何错误,为什么接收方法只被调用一次?还有其他发送视频的方式吗? - Artin Falahi
1个回答

3

我认为你做得很对,不过根据你的需求,UDP套接字可能更合适。尝试将服务器代码更改为以下内容:

while (true)
{
     Socket clientSocket;
     clientSocket = sListen.Accept();

     var converter = new System.Drawing.ImageConverter();
     while(true) // find a better way to determine that the picture is still updating?
    {
        byte[] buffer = (byte[])converter.ConvertTo(_CurrentBitmap, typeof(byte[]));
        clientSocket.Send(buffer, buffer.Length, SocketFlags.None);
    }
}

你之前向客户端发送了一张位图,然后跳出了循环。由于套接字不会保持打开状态,因此客户端只运行了一次循环。


谢谢,它起作用了。如果在服务器循环中发送位图失败,客户端如何重新连接到服务器? - Artin Falahi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接