在 C# 中从单个网络流发送多种类型的数据

发布于 2024-12-11 19:03:04 字数 1667 浏览 0 评论 0原文

我正在创建一个类似于 Microsoft Netmeeting 的程序,因为我必须从单个连接发送多种类型的数据,例如鼠标位置、按下的键以及一次屏幕截图。我成功地向客户端完全发送和接收屏幕截图,但我无法理解如何通过单个连接发送多个数据。

我认为为此目的需要多个端口。一张用于屏幕截图,一张用于鼠标位置,一张用于按下按键。

以下是我正在使用的代码: 服务器 = ScreenShot 的发送者、MousePos 和 Key 的接收者。 客户端 = ScreenShot 的接收者、MousePos 和 Key 的发送者。

服务器:

void StartListen()
{
    try
    {
        IPEndPoint ipendp = new IPEndPoint(IPAddress.Parse(OwnIP()), 532);
        tcpl = new TcpListener(ipendp);
        tcpl.Start();
        s1 = tcpl.AcceptSocket();
        ns = new NetworkStream(s1);
        timer1.Enabled = true;
        while (true)
        {
            byte[] buffer = imageToByteArray(CaptureScreenShot());
            s1.Send(buffer, buffer.Length, SocketFlags.None);
            Thread.Sleep(250);
        }
    }
    catch
    {
        tcpl.Stop();
        ns.Close();
        //tcpl.EndAcceptSocket();
        Form1_Load(0,EventArgs.Empty);
    }
}

客户端:

void StartClient()
{
    try
    {

        IPEndPoint ipendp = new IPEndPoint(IPAddress.Parse(toolStripTextBox1.Text), 532);
        this.Text = "SWare Application - " + toolStripTextBox1.Text + ":532";
        tcpc = new TcpClient();
        tcpc.Connect(ipendp);
        Socket s1 = tcpc.Client;
        ns = tcpc.GetStream();

        while (true)
        {
            byte[] b = new byte[500000];
            s1.Receive(b);
            MemoryStream ms = new MemoryStream(b);
            pictureBox1.Image = Image.FromStream(ms);
            //Thread.Sleep(250);
        }
    }
    catch
    {
        tcpc.Close();
        MessageBox.Show("Disconnected from the Remote PC");
    }
}

I am creating a program similar to Microsoft Netmeeting for that I have to send Multiple type of data from a single connection such as Mouse position, Pressed key and offcourse a screen shot at a time. I am success fully sending and receiving Screen shot to the client but I am unable to understand how multiple data could be send through the single connetion.

I think it require multiple ports for this purpose. One for Screen shot, One for Mouse Pos and One for Key pressed.

Following are the codes I am using:
Server = Sender of ScreenShot, Recever of MousePos and Key.
Client = Receiver of ScreenShot, Sender of MousePos and Key.

Server:

void StartListen()
{
    try
    {
        IPEndPoint ipendp = new IPEndPoint(IPAddress.Parse(OwnIP()), 532);
        tcpl = new TcpListener(ipendp);
        tcpl.Start();
        s1 = tcpl.AcceptSocket();
        ns = new NetworkStream(s1);
        timer1.Enabled = true;
        while (true)
        {
            byte[] buffer = imageToByteArray(CaptureScreenShot());
            s1.Send(buffer, buffer.Length, SocketFlags.None);
            Thread.Sleep(250);
        }
    }
    catch
    {
        tcpl.Stop();
        ns.Close();
        //tcpl.EndAcceptSocket();
        Form1_Load(0,EventArgs.Empty);
    }
}

Client:

void StartClient()
{
    try
    {

        IPEndPoint ipendp = new IPEndPoint(IPAddress.Parse(toolStripTextBox1.Text), 532);
        this.Text = "SWare Application - " + toolStripTextBox1.Text + ":532";
        tcpc = new TcpClient();
        tcpc.Connect(ipendp);
        Socket s1 = tcpc.Client;
        ns = tcpc.GetStream();

        while (true)
        {
            byte[] b = new byte[500000];
            s1.Receive(b);
            MemoryStream ms = new MemoryStream(b);
            pictureBox1.Image = Image.FromStream(ms);
            //Thread.Sleep(250);
        }
    }
    catch
    {
        tcpc.Close();
        MessageBox.Show("Disconnected from the Remote PC");
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

万人眼中万个我 2024-12-18 19:03:04

您可以使用单个连接,但必须为接收者提供一种在读取数据之前区分数据类型(及其大小)的方法。

话虽这么说,如果您正在编写连接的两端(客户端 + 服务器),那么使用 WCF 这样的技术会简单得多。它将允许您传递具有强类型数据的完整类实例,并自动为您处理底层传输(以可配置的方式)。

You can use a single connection, but you have to provide a way for the receiver to differentiate the type of data (and its size) prior to reading it.

That being said, if you're writing both sides of the connection (the client + server), it would be far simpler to use a technology like WCF. It would allow you to pass full class instances with strongly typed data, and take care of the underlying transport (in a configurable way) for you automatically.

下雨或天晴 2024-12-18 19:03:04

简而言之:您可以在流中使用标头。在接收端,您读取标头并进行相应的切换。

对于一个简单的单字节标头,这可能类似于...

类型“a”的发送方:

using (MemoryStream mems = new MemoryStream())
{
    // Store data in MemoryStream
    // It's searchable which may be required
    // ...
    using (TcpClient tcp = newTcpClient())
    {
        using (NetworkStream ns = tcp.GetStream())
        {
            ns.WriteByte((int)'a'); // Store data type header for type 'a'
            mems.WriteTo(ns); // Write serialized data to network
        }
    }
}

接收方:

void receiveData(NetworkStream ns)
{
    using (MemoryStream mems = new MemoryStream())
    {
        int formatByte = ns.ReadByte(); // Read the data type header

        ns.CopyTo(mems);
        mems.Position = 0;

        switch (formatByte)
        {
            case (int)'a': // Type A
                // Read type 'a' from "mems"
                // ...
                break;

            case (int)'b': // Type B
                // Read type 'b' from "mems"
                // ...
                break;

            default:
                // In case you want to point out the unrecognized type
                break;
        }
    }
}

In short: You could use a header in your stream. On the receiving side you read the header and switch accordingly.

With a simple one byte header this might be something along the lines of...

Sender for type 'a':

using (MemoryStream mems = new MemoryStream())
{
    // Store data in MemoryStream
    // It's searchable which may be required
    // ...
    using (TcpClient tcp = newTcpClient())
    {
        using (NetworkStream ns = tcp.GetStream())
        {
            ns.WriteByte((int)'a'); // Store data type header for type 'a'
            mems.WriteTo(ns); // Write serialized data to network
        }
    }
}

Receiver:

void receiveData(NetworkStream ns)
{
    using (MemoryStream mems = new MemoryStream())
    {
        int formatByte = ns.ReadByte(); // Read the data type header

        ns.CopyTo(mems);
        mems.Position = 0;

        switch (formatByte)
        {
            case (int)'a': // Type A
                // Read type 'a' from "mems"
                // ...
                break;

            case (int)'b': // Type B
                // Read type 'b' from "mems"
                // ...
                break;

            default:
                // In case you want to point out the unrecognized type
                break;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文