Is it possible to separate input and output threads with Naudio and AsioOut?
I want to send input and output data over udp protocol and play it.
Now i'm doing it like that -->
private void DefaultConfiguration()
{
var channelCount = _asioOut.DriverInputChannelCount;
var waveFormat = new WaveFormat(SampleRate, 2);
_bufferedWaveProvider = new BufferedWaveProvider(waveFormat) { ReadFully = false };
_asioOut.InitRecordAndPlayback(_bufferedWaveProvider, 2, SampleRate);
_asioOut.DriverResetRequest += OnAsioOutDriverResetRequest;
_asioOut.AudioAvailable += OnUdpAsioOutAudioAvailable;
}
private async void OnUdpAsioOutAudioAvailable(object sender, AsioAudioAvailableEventArgs e)
{
int fullBufferSize = e.SamplesPerBuffer * 4;
byte[] send = new byte[fullBufferSize];
CopyBytes(e.InputBuffers[0], send, 0, fullBufferSize);
await _udpConsumer.SendToAsync(send, SocketFlags.None, _endpoint);
byte[] buffer = new byte[2048];
await _udpConsumer.ReceiveAsync(buffer, SocketFlags.None);
CopyBytes(buffer, e.OutputBuffers[0], 0, 2048);
CopyBytes(buffer, e.OutputBuffers[1], 0, 2048);
e.WrittenToOutputBuffers = true;
}
but i want separate input and output to reduce latency.
Also i tried to do that in this way, but it don't actually help.
private void DefaultConfiguration()
{
var channelCount = _asioOut.DriverInputChannelCount;
var waveFormat = new WaveFormat(SampleRate, 2);
_bufferedWaveProvider = new BufferedWaveProvider(waveFormat) { ReadFully = false };
_asioOut.InitRecordAndPlayback(_bufferedWaveProvider, 2, SampleRate);
_asioOut.DriverResetRequest += OnAsioOutDriverResetRequest;
_asioOut.AudioAvailable += OnUdpAsioOutAudioAvailableInput;
_asioOut.AudioAvailable += OnUdpAsioOutAudioAvailableOutput;
}
private async void OnUdpAsioOutAudioAvailableInput(object sender, AsioAudioAvailableEventArgs e)
{
int fullBufferSize = e.SamplesPerBuffer * 4;
byte[] send = new byte[fullBufferSize];
CopyBytes(e.InputBuffers[0], send, 0, fullBufferSize);
await _udpConsumer.SendToAsync(send, SocketFlags.None, _endpoint);
e.WrittenToOutputBuffers = true;
}
private async void OnUdpAsioOutAudioAvailableOutput(object sender, AsioAudioAvailableEventArgs e)
{
byte[] buffer = new byte[2048];
await _udpConsumer.ReceiveAsync(buffer, SocketFlags.None);
CopyBytes(buffer, e.OutputBuffers[0], 0, 2048);
CopyBytes(buffer, e.OutputBuffers[1], 0, 2048);
e.WrittenToOutputBuffers = true;
}
Related
How can I upload a PDF file to host via C# so that it is available for download via an adroid app? This is what I have tried, but it does not work. What am I doing wrong?
static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
string fileName = ((FTPsetting)e.Argument).Filename;
string fullName = ((FTPsetting)e.Argument).FullName;
string username = ((FTPsetting)e.Argument).Username;
string password = ((FTPsetting)e.Argument).Password;
string server = ((FTPsetting)e.Argument).Server;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(string.Format("{0}/{1}", server, fileName)));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
Stream ftpstream = request.GetRequestStream();
FileStream fs = File.OpenRead(fullName);
byte[] buffer = new byte[1024];
double total = (double)fs.Length;
int byteread = 0;
double read = 0;
do
{
if (!backgroundWorker.CancellationPending)
{
byteread = fs.Read(buffer, 0, 1024);
ftpstream.Write(buffer, 0, byteread);
read += (double)byteread;
double percontage = read / total * 100;
backgroundWorker.ReportProgress((int)percontage);
}
}
while (byteread != 0);
fs.Close();
ftpstream.Close();
}
static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("Completed" + e.ProgressPercentage + "%");
}
I'm working in a remote administration tool to my own use and the project is stopped because a error on receiver function on Server side that is this.:
Arithmetic operation resulted in an overflow. (Adding integers)
in this line:
var imageData = new byte[length];
void server_Received(Listener l, Info i, string received) {
string[] cmd = received.Split('|');
switch (cmd[1])
{
case "PRINT":
//MessageBox.Show("print");
Thread threadPrint;
threadPrint = new Thread(() =>
{
var lengthData = new byte[4];
var lengthBytesRead = 0;
while (lengthBytesRead < lengthData.Length)
{
var read = i.sock.Receive(lengthData, lengthBytesRead, lengthData.Length - lengthBytesRead, SocketFlags.None);
if (read == 0) return;
lengthBytesRead += read;
}
var length = BitConverter.ToInt32(lengthData, 0);
var imageData = new byte[length];
var imageBytesRead = 0;
while (imageBytesRead < imageData.Length)
{
var read = i.sock.Receive(imageData, imageBytesRead, imageData.Length - imageBytesRead, SocketFlags.None);
if (read == 0) return;
imageBytesRead += read;
}
using (var stream = new MemoryStream(imageData))
{
var bitmap = new Bitmap(stream);
Invoke(new ImageCompleteDelegate(ImageComplete), new object[] { bitmap });
}
});
threadPrint.Start();
break;
}
}
the code to receiver i taked from this reference (see Client code) and was adapted to my need like you can see above.
Here is how i'm sending the bitmap on android (Java):
try {
dos = new DataOutputStream(SocketBackgroundService.xclientSocket.getOutputStream());
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(dos)
)
);
out.println("|PRINT|");
out.flush();
dos.writeInt(array.length);
dos.write(array, 0, array.length);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
Then, i want know what can be done to solve this trouble?
Thanks in advance.
The solution was insert:
Array.Reverse(lengthData);
before of:
var length = BitConverter.ToInt32(lengthData, 0);
I am trying to achieve multithreaded AES encryption using Backgroundworker to get the events done. First I read the buffer send it to doworker event. That writes the inbuffer to outbuffer encrypted after the thread is done it needs to write in the RunWorkerCompleted method but it never gets called.
However when I slowly debug using a messagebox, the function fires up! successfully giving me my encrypted file. I don't understand any of this I would appreciate if somebody could help me how to translate this to a threadpool? or maybe explain why it doesn't call runworkercomplete when it is done because it show me the messagebox in the doworker event but not in the runworkercomplete event???
static List<BackgroundWorker> listWorkers = new List<BackgroundWorker>();
static List<BackgroundWorker> listFreeWorkers = new List<BackgroundWorker>();
static FileStream fsIn;
static string file;
static byte[] key;
const int BLOCK_SIZE = 1000;
static FileStream outFile;
public static void EncryptFile(string inputFile, string outputFile, string sKey, String privateKey, ProgressBar progress)
{
String fileName = inputFile;
fileName = "\\" + fileName.Split('\\').Last();
var progres = new Progress<int>(value => progress.Value = value);
file = outputFile + fileName;
fsIn = new FileStream(inputFile, FileMode.Open);
outFile = new FileStream(file, FileMode.Create);
key = new UnicodeEncoding().GetBytes(sKey);
for (int t = 0; t < 4; t++)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
listWorkers.Add(worker);
listFreeWorkers.Add(worker);
}
FileInfo fileInfo = new FileInfo(inputFile);
double numBlocks = Math.Ceiling(((double)fileInfo.Length) / BLOCK_SIZE);
int ixCurrentBlock = 0;
while (ixCurrentBlock < numBlocks)
{
if (listFreeWorkers.Count > 0)
{
BackgroundWorker freeWorker = listFreeWorkers[0];
listFreeWorkers.Remove(freeWorker);
int bytes;
if (ixCurrentBlock < numBlocks - 1)
{
byte[] buffer = new byte[BLOCK_SIZE];
bytes = fsIn.Read(buffer, 0, BLOCK_SIZE);
freeWorker.RunWorkerAsync(Tuple.Create(ixCurrentBlock * BLOCK_SIZE, buffer));
}
else //special handling for last block
{
int size = (int)(fileInfo.Length - ixCurrentBlock * BLOCK_SIZE);
byte[] buffer = new byte[size];
bytes = fsIn.Read(buffer, 0, size);
freeWorker.RunWorkerAsync(Tuple.Create(0, buffer));
}
ixCurrentBlock++;
}
else
{
}
}
var hasAllThreadsFinished1 = (from worker in listWorkers
where worker.IsBusy
select worker).ToList().Count;
while (hasAllThreadsFinished1 != 0)
{
hasAllThreadsFinished1 = (from worker in listWorkers
where worker.IsBusy
select worker).ToList().Count;
}
fsIn.Close();
outFile.Close();
byte[] hash = Hashing.HashFile(outputFile + fileName, privateKey);
File.WriteAllBytes(outputFile + "\\Hashing.txt", hash);
}
private static void worker_DoWork(object sender, DoWorkEventArgs e)
{
Tuple<int, byte[]> t = e.Argument as Tuple<int, byte[]>;
//int blockIndex = (int)t.Item1;
byte[] inBuffer = (byte[])t.Item2;
byte[] outBuffer;
MessageBox.Show("Started");
using (MemoryStream outStream = new MemoryStream())
{
RijndaelManaged RMCrypto = new RijndaelManaged();
using (CryptoStream cs = new CryptoStream(outStream,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write))
{
// I want to write inbuffer non encrypted to outbuffer encrypted.
cs.Write(inBuffer, 0, inBuffer.Length);
}
outBuffer = outStream.ToArray();
}
e.Result = Tuple.Create(0, outBuffer);
MessageBox.Show("done function");
}
static Object pen = new Object();
private static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done");
Tuple<int, byte[]> t = e.Result as Tuple<int, byte[]>;
//int blockIndex = (int)t.Item1;
byte[] buffer = (byte[])t.Item2;
bool b = true;
while (b)
{
lock (pen)
{
outFile.Write(buffer, 0, buffer.Length);
listFreeWorkers.Add((BackgroundWorker)sender);
MessageBox.Show("Done");
b = false;
}
}
}
UPDATE:
The error tends to be when 4 threads are running at the same time. They simply get stuck I tested using a messageBox here.
using (CryptoStream cs = new CryptoStream(outStream,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write))
{
// I want to write inbuffer non encrypted to outbuffer encrypted.
cs.Write(inBuffer, 0, inBuffer.Length);
}
outBuffer = outStream.ToArray();
MessageBox.Show(outBuffer[0] + " done function");
Will give me the encrypt file. This makes no sense why can't my threads run the dowork method at the same time :(?
As you don't specify a Block cipher mode for RijndaelManaged() you get the default CBC mode. In CBC mode each block encrypted / decrypted are made dependent of the previous block. This prevents encrypt and decrypt of the individual blocks to be done in parallel.
hi people I'm trying to put a download progress bar to my ftp download program it kinda works but progress bar is not filling with the download or after download but i get the download completed message the code is below ;
public void yap(object o)
{
(o as Label).Text = "DOWNLOADING";
}
private void button1_Click(object sender, EventArgs e)
{
CheckForIllegalCrossThreadCalls = false;
ParameterizedThreadStart p = new ParameterizedThreadStart(yap);
Thread t = new Thread(p);
t.Start(label2);
BackgroundWorker _backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += _backgroundWorker_DoWork;
_backgroundWorker.WorkerReportsProgress = true;
_backgroundWorker.ProgressChanged +=
new ProgressChangedEventHandler(_backgroundWorker_ProgressChanged);
_backgroundWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted);
_backgroundWorker.RunWorkerAsync();
}
void _backgroundWorker_RunWorkerCompleted
(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Download Completed");
}
void _backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void Form1_Load(object sender, EventArgs e)
{
AutoSizeMode = AutoSizeMode.GrowAndShrink;
progressBar1.Maximum = 100;
}
void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
Dispatcher.CurrentDispatcher.Invoke
(System.Windows.Threading.DispatcherPriority.Background,new Action(delegate()
{
string yol = Environment.CurrentDirectory;
FtpWebRequest FTP;
try
{
FileStream SR = new FileStream(yol + "\\list.gz", FileMode.Create);
FTP = (FtpWebRequest)FtpWebRequest.Create(new Uri
("ftp://" + textBox1.Text + "/" + "/usr/valapp/etc/list.gz"));
FTP.Credentials = new NetworkCredential("username", "password");
FTP.Method = WebRequestMethods.Ftp.DownloadFile;
FTP.UseBinary = true;
FtpWebResponse response = (FtpWebResponse)FTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
SR.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
ftpStream.Close();
SR.Close();
response.Close();
MessageBox.Show("File Downloaded!");
for (int i = 0; i <= 100; i++)
{
backgroundWorker1.ReportProgress(i);
System.Threading.Thread.Sleep(20);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
}));
}
}
}
Code might be look complex but its totally works as i told only progress bar is not filling thank you.
int cnt=0;
double totalentry=response.ContentLength/bufferSize;
while (readCount > 0)
{
SR.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
if(_backgroundWorker.WorkerReportsProgress)
{
_backgroundWorker.ReportProgress(cnt++*100/(int)totalentry);
}
}
You may just edit this part of the code.
So my problem is the my server cannot receive all the data the client is sending , which is causing virtually no packets to be getting received at all on server side.
Basically the problem is I need to quite heavily sleep the CLientLoop , in order for the sent data to be received. as in Thread.Sleep(1000)
(This is been tested locally)
My server code is here :
public void RecieveAsync()
{
socket.BeginReceive(lenBuffer, 0, lenBuffer.Length, SocketFlags.None,recieveCallBack, null);
}
private void recieveCallBack(IAsyncResult ar)
{
int rec = socket.EndReceive(ar);
if (rec == 0)
{
if (Disconnected != null)
{
Disconnected(this);
return;
}
if (rec != 4)
{
throw new Exception();
}
}
/
buffer = new ReceiveBuffer(BitConverter.ToInt32(lenBuffer, 0));
Also my buffer class for those interested (Might help)
\ public struct ReceiveBuffer
{
public const int BUFFER_SIZE = 1024;
public byte[] Buffer;
public int ToReceive;
public MemoryStream BufStream;
public ReceiveBuffer(int toRec)
{
Buffer = new byte[BUFFER_SIZE];
ToReceive = toRec;
BufStream = new MemoryStream(toRec);
}
public void Dispose()
{
Buffer = null;
ToReceive = 0;
Close();
if (BufStream != null) BufStream.Dispose();
}
public void Close()
{
if (BufStream != null && BufStream.CanWrite)
{
BufStream.Close();
}
}
So my client is sending the data in this method
public void Send(byte[] data, int index, int length)
{
//add data as state
socket.BeginSend(BitConverter.GetBytes(length), 0, 4, SocketFlags.None, new AsyncCallback(sendCallback), data);
socket.BeginSend(data, index, length, SocketFlags.None, new AsyncCallback(sendCallback), null);
}
Where the information being sent is here
public void ClientLoop()
{
try{
Console.WriteLine("In Client loop");
client.DataRecieved +=new Client.DataRecievedEventHandler(Client_DataRecieved);
while (true)
{
byte[] playerData = PreparePlayerData();
client.Send(playerData, 0, playerData.Length);
//client.RecieveAsync();
Thread.Sleep(10);
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
}
with
public byte[] PreparePlayerData()
{
BinaryWriter bw = new BinaryWriter(new MemoryStream());
bw.Write((int)Commands.Text);
string data = "";
string Position = Math.Round(MultiplayerScreen.localPlayer.Position.X, 2).ToString() + "|" + Math.Round(MultiplayerScreen.localPlayer.Position.Y, 2).ToString();
string effects = (MultiplayerScreen.localPlayer.Effects == Microsoft.Xna.Framework.Graphics.SpriteEffects.None) ? "0" : "1";
string animaton = (MultiplayerScreen.localPlayer.Animation.MoveState).ToString();
string frame = MultiplayerScreen.localPlayer.Animation.XFrame.ToString();
data = "P|" + Position + "|" + effects + "|" + animaton + "|" + frame;
bw.Write(data);
bw.Close();
byte[] toSend = ((MemoryStream)bw.BaseStream).ToArray();
bw.BaseStream.Dispose();
return toSend;
}
Also this is the method where the server processes the data received
void Client_DataRecieved(Client sender, ReceiveBuffer e)
{
BinaryReader r = new BinaryReader(e.BufStream);
Commands header = (Commands)r.ReadInt32();
string s = r.ReadString();
Console.WriteLine("Client has received " + s);
switch (header)
{
case Commands.Player:
{
HandlePlayerData(s);
Console.WriteLine("The player data has been updated");
}
break;
case Commands.Text:
{
if (s.StartsWith("clientAccepted"))
{
connectedPlayer.isOnline = true;
}
if (s.StartsWith("P|"))
{
s = s.Remove(0, 2);
HandlePlayerData(s);
}
}
break;
}
}
socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallback, null);
}
void receivePacketCallback(IAsyncResult ar)
{
int rec = socket.EndReceive(ar);
if (rec <= 0)
{
return;
}
buffer.BufStream.Write(buffer.Buffer, 0, rec);
buffer.ToReceive -= rec;
if (buffer.ToReceive > 0)
{
Array.Clear(buffer.Buffer, 0, buffer.Buffer.Length);
socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallback, null);
return;
}
if (DataRecieved != null)
{
buffer.BufStream.Position = 0;
DataRecieved(this, buffer);
}
buffer.Dispose();
}