Отправка нескольких типов данных из одного сетевого потока в C # - PullRequest
1 голос
/ 26 октября 2011

Я создаю программу, аналогичную Microsoft Netmeeting, для которой мне нужно отправлять данные нескольких типов из одного подключения, например, положение мыши, нажатую клавишу и снимать экранный снимок за раз.Я успешно отправляю и получаю снимок экрана для клиента, но не могу понять, как несколько данных могут быть отправлены через одно соединение.

Я думаю, что для этой цели требуется несколько портов.Один для снимка экрана, один для мыши и один для нажатой клавиши.

Ниже приведены коды, которые я использую: Сервер = Отправитель ScreenShot, Получатель MousePos и ​​Ключ.Клиент = Получатель ScreenShot, Отправитель MousePos и ​​Ключ.

Сервер:

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");
    }
}

Ответы [ 2 ]

1 голос
/ 20 марта 2012

Короче говоря: Вы можете использовать заголовок в своем потоке. На принимающей стороне вы читаете заголовок и переключаетесь соответственно.

С простым однобайтовым заголовком это может быть что-то вроде ...

Отправитель для типа '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;
        }
    }
}
1 голос
/ 26 октября 2011

Вы можете использовать одно соединение, но вы должны предоставить приемнику способ различать тип данных (и их размер) до их чтения.

Тем не менее, если вы пишете обе стороны соединения (клиент + сервер), было бы гораздо проще использовать такую ​​технологию, как WCF. Это позволит вам автоматически передавать экземпляры классов со строго типизированными данными и автоматически заботиться о базовом транспорте (настраиваемым образом).

...