2 Replies - 13427 Views - Last Post: 16 August 2011 - 08:58 AM Rate Topic: -----

#1 cokacola  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 64
  • Joined: 23-July 10

Sending a byte array over a network

Posted 16 August 2011 - 05:05 AM

I have been trying(for several hours) to send audio over a network.
I can play the sound fine, but my problem is sending it over the network.
I can't seem to get the array from the client to the server(the server doesn't send anything, it just receives from the one client).
Well, actually, it does send, but its reassembling it that is the problem.
I am using Lidgren for this right now, oh, and the sound is actually Text to Speech that is generated into a stream on the client.
Now, I will post my client/server code.

Server:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Configuration;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;
using CoreAudioApi;
//using SlimDX.Multimedia;
using NAudio;
using NAudio.Wave;
using NAudio.Wave.Asio;
using NAudio.Wave.Compression;
using NAudio.Wave.SampleProviders;
using NAudio.Wave.WaveFormats;
using Lidgren.Network;

namespace VServer
{
    class Program
    {
        private static NetServer server;
        protected const int LIMIT = 5;

        protected static MMDevice m_device;
        protected static bool m_bUpdate = true;
        static void Main(string[] args)
        {
            //try
            //{
                NetPeerConfiguration conf = new NetPeerConfiguration("VoiceServerNet");
                conf.Port = 7058;
                conf.EnableUPnP = true;

                server = new Lidgren.Network.NetServer(conf);

                server.Start();
                //server.RegisterReceivedCallback(new SendOrPostCallback(GotMessage));
                /*NetIncomingMessage msg;
                while ((msg = server.ReadMessage()) != null) //I also tried this during the process
                {
                    // process message here
                    Console.WriteLine("MSG");
                    GotMessage(msg);
                }*/
                MMDeviceEnumerator devEnum = new MMDeviceEnumerator();
                m_device = devEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
                while (true)
                {
                    server.MessageReceivedEvent.WaitOne(); // this will block until a message arrives
                    Console.WriteLine("Recieved");
                    var msg = server.ReadMessage();
                    GotMessage(msg);
                }
            //}
           // catch(Exception err)
            //{
              //  Console.WriteLine("Error: " + err.Message);
            //}
            Console.ReadKey();
        }


        private static ulong s_length;
        private static ulong s_received;
        private static FileStream s_writeStream;
        private static int s_timeStarted;

        public static void GotMessage(NetIncomingMessage inc)
        {
            //var inc = server.ReadMessage();
            if (inc.MessageType == NetIncomingMessageType.Data)
            {
                int chunkLen = inc.LengthBytes;
                if (s_length == 0)
                {
                    s_length = inc.ReadUInt64();
                    string filename = "localfile.wav";
                    s_writeStream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
                    s_timeStarted = Environment.TickCount;
                    //return;
                }
                else
                {
                    byte[] all = inc.ReadBytes(inc.LengthBytes);
                    s_received += (ulong)all.Length;
                    s_writeStream.Write(all, 0, all.Length);

                    int v = (int)(((float)s_received / (float)s_length) * 100.0f);

                    if (s_received >= s_length)
                    {
                        int passed = Environment.TickCount - s_timeStarted;
                        double psec = (double)passed / 1000.0;
                        double bps = (double)s_received / psec;

                        MemoryStream waveStream = new MemoryStream(all);
						NAudio.Wave.WaveFileReader wa = new WaveFileReader(waveStream);
						WaveChannel32 stram = new WaveChannel32(wa);
						NAudio.Wave.WaveOut outplr = new WaveOut();
						outplr.Init(stram);
						outplr.Play();
						waveStream.Close();
						
						s_writeStream.Flush();
                        s_writeStream.Close();
                        s_writeStream.Dispose();
                    }
                    m_device.AudioEndpointVolume.Mute = false;

                    //FileStream waveStream = new FileStream("localfile.wav", FileMode.Open, FileAccess.Read);
                    
                }
            }
            
            // process message here
        } 
    }
}



Client:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
//using NetSockets;
//using SlimDX.Multimedia;
using NAudio;
using NAudio.Wave;
using NAudio.Wave.Asio;
using NAudio.Wave.Compression;
using NAudio.Wave.SampleProviders;
using NAudio.Wave.WaveFormats;
using Lidgren.Network;


namespace VoiceClient
{
    public partial class Form1 : Form
    {
        //private Stream s = new MemoryStream();
        private NetClient client;
        private System.Speech.Synthesis.SpeechSynthesizer sp = new System.Speech.Synthesis.SpeechSynthesizer();
        private Stream strm = new MemoryStream();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                NetPeerConfiguration conf = new NetPeerConfiguration("VoiceServerNet");
                //conf.Port = 7058;
                conf.EnableUPnP = true;
                client = new NetClient(conf);
                client.Start();
                client.Connect("10.0.0.4", 7058);
                

            }
            catch(Exception err)
            {
                MessageBox.Show(err.Message, "Connection Error");
            }
        }

        
        private void button1_Click(object sender, EventArgs e)
        {
                try
                {
                    sp.SetOutputToWaveStream(strm);


                    sp.SpeakAsync(textBox1.Text);
                    sp.SpeakCompleted += new EventHandler<System.Speech.Synthesis.SpeakCompletedEventArgs>(sp_SpeakCompleted);
                }
                catch(Exception err)
                {
                    MessageBox.Show(err.Message, "Error");
                }
        }

        void sp_SpeakCompleted(object sender, System.Speech.Synthesis.SpeakCompletedEventArgs e)
        {
            
            //MessageBox.Show(ASCIIEncoding.ASCII.GetString(send), "test");*/
            try
            {
                //MessageBox.Show("hi");
                if (client.ConnectionStatus != NetConnectionStatus.Disconnected)
                {
                    byte[] send = ReadToEnd(strm);
                    NetOutgoingMessage msg = client.CreateMessage();
                    msg.Write(send);

                    client.SendMessage(msg, NetDeliveryMethod.ReliableOrdered);
                }
                else
                {
                    MessageBox.Show("Not connected!", "Error");
                }
            }
            catch(Exception err)
            {
                MessageBox.Show(err.Message, "Error");
            }
        }

        public static byte[] ReadToEnd(System.IO.Stream stream)
        {
            long originalPosition = stream.Position;
            stream.Position = 0;

            try
            {
                byte[] readBuffer = new byte[4096];

                int totalBytesRead = 0;
                int bytesRead;

                while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
                {
                    totalBytesRead += bytesRead;

                    if (totalBytesRead == readBuffer.Length)
                    {
                        int nextByte = stream.ReadByte();
                        if (nextByte != -1)
                        {
                            byte[] temp = new byte[readBuffer.Length * 2];
                            Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                            Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                            readBuffer = temp;
                            totalBytesRead++;
                        }
                    }
                }

                byte[] buffer = readBuffer;
                if (readBuffer.Length != totalBytesRead)
                {
                    buffer = new byte[totalBytesRead];
                    Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
                }
                return buffer;
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message, "Error");
                return new byte[100];
            }
            finally
            {
                stream.Position = originalPosition;
            }
        }
    }
}


The "GotMessage" method on the server is being run, so its not the receive part.

Can anyone tell me what is so horribly wrong here?

Is This A Good Question/Topic? 0
  • +

Replies To: Sending a byte array over a network

#2 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5631
  • View blog
  • Posts: 12,078
  • Joined: 02-June 10

Re: Sending a byte array over a network

Posted 16 August 2011 - 08:07 AM

Because of all the 3rd party stuff it would be hard for any of us to duplicate the project and run it locally.

But I would start by doing this:
Using a very short sound, get the full byte[] on the sending side.
Then send it. You say you get a "GotMessage" alert on the other end.
Then get the byte[] that is received. Compare the two.

If you sent
1
2
3
4
5
but received
01
02
03
04
05
123

You would see where the data was changed in transmission.

You can't just assume that "GotMessage" means the array is intact.

Why are you using all this third party stuff anyway? Sending a byte[] over a network isn't really tough. There are lots of networking tutorials here on DIC. If you got rid of the layers of 3rd party you wouldn't have to wonder if they are somehow trying interpret your data and screwing it up.

This post has been edited by tlhIn`toq: 16 August 2011 - 08:07 AM

Was This Post Helpful? 0
  • +
  • -

#3 cokacola  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 64
  • Joined: 23-July 10

Re: Sending a byte array over a network

Posted 16 August 2011 - 08:58 AM

Yea, I rewrote it using C# sockets, and almost have it working.
Just got to work out the "Stream doesn't support seek operations", but thats not too hard.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1