UWP with UDP StreamWriter in OSC format - c#

I have following class take care the udp Sending
public static async Task SendStringUdpAsync(HostName remoteHost,
string remotePort, string message)
{
using (var socket = new DatagramSocket())
{
var stream = (await socket.GetOutputStreamAsync(
remoteHost, remotePort)).AsStreamForWrite();
using (var writer = new StreamWriter(stream))
{
await writer.WriteLineAsync(message.ToString());
await writer.FlushAsync();
}
}
}
But instead send a string, I want to send a custom class in udp
public class OSCString : IOSCValue<string>
{
static int PaddingLength = 4;
public string Contents { get; }
public char TypeTag { get { return 's'; }}
public byte[] Bytes { get; }
public OSCString(string contents)
{
Contents = contents;
Bytes = GetBytes();
}
public byte[] GetBytes()
{
byte[] bytes = new byte[GetByteLength()];
Encoding.ASCII.GetBytes(Contents, 0, Contents.Length, bytes, 0);
return bytes;
}
public int GetByteLength()
{
return GetPaddedLength(Contents.Length);
}
public static int GetPaddedLength(int length)
{
int terminatedLength = length + 1;
int paddedLength = (int)(Math.Ceiling(terminatedLength / (float)PaddingLength) * 4);
return paddedLength;
}
public static OSCString Parse(BinaryReader reader)
{
List<byte> bytes = new List<byte>();
byte current = reader.ReadByte();
while(current != 0)
{
bytes.Add(current);
current = reader.ReadByte();
}
string str = Encoding.ASCII.GetString(bytes.ToArray());
OSCString oscString = new OSCString(str);
int bytesToBurn = oscString.Bytes.Length - bytes.Count - 1;
for(int i = 0; i < bytesToBurn; i++)
{
reader.ReadByte();
}
return oscString;
}
}
I try DataWriter and StreamWrite, dont work too well.
The UWP take out the socket class, is there any Streamwrite can do the job?

I figure this out
var socket = new DatagramSocket();
//socket.MessageReceived += SocketOnMessageReceived;
using (var stream = await socket.GetOutputStreamAsync(remoteHost, remotePort))
{
using (var writer = new DataWriter(stream))
{
// var data = Encoding.UTF8.GetBytes(message);
writer.WriteBytes(packet.Bytes);
writer.StoreAsync();
}
}
Everything works great!!!!!!!!!

Related

How to create a MemoryStream packet and extract relevant data from NetworkStream?

I've created packetReader & packetBuilder for passing and receiving packets that contain string message (using TcpClient and TcpListener in the server)
and I'm trying to do the same with byte[].
Here is how the message packet is built :
How to implement the same WriteCanvasStrokes() and ReadCanvasStrokes() ?
Here is how I send to server:
TcpClient _client;
public void SendMessageToServer(string message)
{
var messagePacket = new PacketBuilder();
messagePacket.WriteOpCode(5);
messagePacket.WriteMessage(message);
_client.Client.Send(messagePacket.GetPacketBytes());
}
public void SendCanvasStrokesToServer(MemoryStream memoryStream)
{
var strokesPacket = new PacketBuilder();
strokesPacket.WriteOpCode(7);
strokesPacket.WriteCanvasStrokes(memoryStream.GetBuffer());
_client.Client.Send(strokesPacket.GetPacketBytes());
}
PacketBuilder :
public class PacketBuilder
{
MemoryStream _ms;
public PacketBuilder()
{
_ms = new MemoryStream();
}
public void WriteOpCode(byte opcode)
{
_ms.WriteByte(opcode);
}
public void WriteMessage(string msg)
{
var msgLength = msg.Length;
_ms.Write(BitConverter.GetBytes(msgLength));
_ms.Write(Encoding.ASCII.GetBytes(msg));
}
public void WriteCanvasStrokes(byte[] strokes)
{
_ms.Write(BitConverter.GetBytes(strokes.Length));
_ms.Write(strokes);
}
public Byte[] GetPacketBytes()
{
return _ms.ToArray();
}
}
PacketReader :
public class PacketReader : BinaryReader
{
private NetworkStream _ns;
public PacketReader(NetworkStream ns) : base(ns)
{
_ns = ns;
}
public string ReadMessage()
{
byte[] msgBuffer;
var length = ReadInt32();
msgBuffer = new byte[length];
_ns.Read(msgBuffer, 0, length);
var msg = Encoding.ASCII.GetString(msgBuffer);
return msg;
}
public byte[] ReadCanvasStrokes()
{
byte[] strokesBuffer;
var length = ReadInt32();
strokesBuffer = new byte[length];
_ns.Read(strokesBuffer, 0, length);
return strokesBuffer;
}
}

Filestream.readtimeout: invalid operation exception

I want to download file (.PDF as an example) using File stream. Here is a contrived example:
public ActionResult GetPDF()
{
ActionResult ar = null;
FileStream fs = null;
try
{
fs = System.IO.File.OpenRead(filename);
var bytes = new byte[fs.Length];
var x = fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
abcd fr = new abcd(fs, "application/pdf");
}
catch(Exception)
{
}
return ar;
}
public class CheckedFileStreamResult : FileStreamResult
{
public bool DownloadCompleted { get; set; }
public CheckedFileStreamResult(FileStream stream, string contentType)
: base(stream, contentType)
{
DownloadCompleted = false;
}
protected override void WriteFile(HttpResponseBase response)
{
var outputStream = response.OutputStream;
response.BufferOutput = false;
using (FileStream)
{
var buffer = new byte[_bufferSize];
var count = FileStream.Read(buffer, 0, _bufferSize);
while (count != 0 && response.IsClientConnected)
{
outputStream.Write(buffer, 0, count);
count = FileStream.Read(buffer, 0, _bufferSize);
}
DownloadCompleted = response.IsClientConnected;
}
}
private const int _bufferSize = 0x1000;
}
public class abcd : CheckedFileStreamResult
{
public abcd(FileStream stream, string contentType) : base(stream, contentType)
{
DownloadCompleted = false;
}
public void Write(HttpResponseBase response)
{
WriteFile(response);
}
}
I always get count with value 0. Invalid Operation Exception is thrown here:
var count = FileStream.Read(buffer, 0, _bufferSize);
Please guide me how can I proceed. I want to know whether the file was downloaded successfully.

how to write json file with size limit (100KB) and once size cross, write new file?

I have a blocking collection which gets filled with data by some app1.
I have subscribed to that blocking collection and need to write a file with below case,
start writing a file .
if the file size crossed 100kb, close the first file and starts a new file.
and if there is no data coming from app1, lets say for 1 minute, then close the file.
Currently with below code, I'm only able to write per blocking collection into per file, how to proceed with my above requirement, please suggest.
class Program
{
private static BlockingCollection<Message> messages = new BlockingCollection<Message>();
private static void Producer()
{
int ctr = 1;
while (true)
{
messages.Add(new Message { Id = ctr, Name = $"Name-{ctr}" });
Thread.Sleep(1000);
ctr++;
}
}
private static void Consumer()
{
foreach (var message in messages.GetConsumingEnumerable())
{
Console.WriteLine(JsonConvert.SerializeObject(message));
using (var streamWriter = File.CreateText(Path.Combine(#"C:\TEMP", $"File-{ DateTime.Now.ToString("yyyyMMddHHmmssfff")}.json")))
{
using (var writer = new JsonTextWriter(streamWriter))
{
writer.Formatting = Formatting.Indented;
writer.WriteStartObject();
writer.WritePropertyName("Data");
writer.WriteStartArray();
writer.WriteRawValue(JsonConvert.SerializeObject(message));
writer.WriteEndArray();
writer.WriteEndObject();
}
}
}
}
static void Main(string[] args)
{
var producer = Task.Factory.StartNew(() => Producer());
var consumer = Task.Factory.StartNew(() => Consumer());
Console.Read();
}
}
This will take the messages with any size and divided it to a different JSON file. You need to specify the size using maxchar. before that, you have to check the size of the last file like this and you have to pass the same file name and the new size if else create a new file and divide the message.
using System;
using System.IO;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Collections;
using Newtonsoft.Json;
using System.Runtime.Remoting.Messaging;
using System.Text;
namespace Program
{
class Program
{
public static string last_path = "";
public static readonly string BYE = "bye";
private static BlockingCollection<Message> messages = new BlockingCollection<Message>();
private static void Producer()
{
int ctr = 1;
while (true)
{
messages.Add(new Message { Id = ctr, Name = $"Name-{ctr}" });
Thread.Sleep(1000);
ctr++;
}
}
private static void Consumer()
{
foreach (var message in messages.GetConsumingEnumerable())
{
Console.WriteLine(JsonConvert.SerializeObject(message));
string json = JsonConvert.SerializeObject(message);
int maxchar = 102400;
if (last_path != "")
{
long length = new FileInfo(last_path).Length;
if (length < maxchar)
{
maxchar = maxchar - unchecked((int)length);
dividefile(last_path, maxchar, json);
}
else
{
dividefile("", maxchar, json);
}
}
else
{
dividefile("", maxchar, json);
}
}
}
public static void dividefile(string path, int maxchar, string message)
{
//FileStream fileStream = new FileStream(yourfile, FileMode.Open, FileAccess.Read);
byte[] byteArray = Encoding.UTF8.GetBytes(message);
MemoryStream stream = new MemoryStream(byteArray);
using (StreamReader streamReader = new StreamReader(stream))
{
Int64 x1 = stream.Length;
char[] fileContents = new char[maxchar];
int charsRead = streamReader.Read(fileContents, 0, maxchar);
// Can't do much with 0 bytes
if (charsRead == 0)
throw new Exception("File is 0 bytes");
while (charsRead > 0)
{
x1 = x1 - maxchar;
if (x1 > 0)
{
string s = new string(fileContents);
if (path == "")
{
last_path = Path.Combine(#"C:\TEMP", $"File-{ DateTime.Now.ToString("yyyyMMddHHmmssfff")}.json");
path = "";
}
else
{
last_path = path;
}
AppendTransaction(last_path, s);
charsRead = streamReader.Read(fileContents, 0, maxchar);
}
else
{
int m = (int)(((x1 + maxchar) % maxchar));
string messagechunk = new string(fileContents, 0, m);
if (path == "")
{
last_path = Path.Combine(#"C:\TEMP", $"File-{ DateTime.Now.ToString("yyyyMMddHHmmssfff")}.json");
path = "";
}
else
{
last_path = path;
}
AppendTransaction(last_path, messagechunk);
charsRead = streamReader.Read(fileContents, 0, m);
}
}
}
}
private static void AppendTransaction(string path , string transaction)
{
string filename = path;
bool firstTransaction = !File.Exists(filename);
JsonSerializer ser = new JsonSerializer();
ser.Formatting = Formatting.Indented;
ser.TypeNameHandling = TypeNameHandling.Auto;
using (var fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))
{
Encoding enc = firstTransaction ? new UTF8Encoding(true) : new UTF8Encoding(false);
using (var sw = new StreamWriter(fs, enc))
using (var jtw = new JsonTextWriter(sw))
{
if (firstTransaction)
{
sw.Write("[");
sw.Flush();
}
else
{
fs.Seek(-Encoding.UTF8.GetByteCount("]"), SeekOrigin.End);
sw.Write(",");
sw.Flush();
}
ser.Serialize(jtw, transaction);
sw.Write(']');
}
}
}
static void Main(string[] args)
{
var producer = Task.Factory.StartNew(() => Producer());
var consumer = Task.Factory.StartNew(() => Consumer());
Console.Read();
}
class Message
{
public int ProductorThreadID { get; set; }
public int CustomerThreadID { get; set; }
public string key { get; set; }
public string content { get; set; }
public string Name { get; internal set; }
public int Id { get; internal set; }
public bool endThread()
{
return string.Compare(key, Program.BYE) == 0;
}
public string ToString(bool isProductor)
{
return string.Format("{0} Thread ID {1} : {2}", isProductor ? "Productor" : "Customer",
isProductor ? ProductorThreadID.ToString() : CustomerThreadID.ToString(),
content);
}
}
}
}

Background work completed never fired

After background process DoWork() the control is exit from the block but it never fire a RunWorkerCompleted() and one more thing is isBusy is still true
Please help me
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
sendFile.Send();
}));
This is my FileReadWrite.cs file
Whenever I used this file in xaml class file it worked but there I am using Dispatcher in DispatcherObject class from WindowBase.dll but in another .cs file I can't use that DispatcherObject class that's why I am using Dispatcher.CurrentDispatcher.Invoke()
public class FileReadWrite
{
public int SourceId;
public int DestinationId;
public string FileName;
public WebSocket WebSocket;
public int SplitSize;
public int ReferenceId;
BinaryWriter _binaryWriter;
public int _totalsequence = 0;
public int progvalue;
public static double totallength;
public static double calculate, sendlen;
public static int post;
public double calc, count, len, sentsize;
public static int FileSendCount = 0;
public static List<byte[]> FileList = new List<byte[]>();
public BackgroundWorker _worker = new BackgroundWorker();
public FileReadWrite()
{
_worker.DoWork += _worker_DoWork;
_worker.RunWorkerCompleted += _worker_RunWorkerCompleted;
}
void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
FileCloseMessage fileclosemsg = new FileCloseMessage();
fileclosemsg.Source = SourceId;
fileclosemsg.Destination = DestinationId;
fileclosemsg.Date = DateTime.Now;
fileclosemsg.Sequenceno = 0;
fileclosemsg.totalsequence = _totalsequence;
byte[] bytess = fileclosemsg.GetBytes();
FileList.Add(bytess);
}
void _worker_DoWork(object sender, DoWorkEventArgs e)
{
using (BinaryReader b = new BinaryReader(File.Open(FileName, FileMode.Open)))
{
int pos = 0;
int length = (int)b.BaseStream.Length;
totallength = Convert.ToDouble(length);
byte[] bytes = new byte[SplitSize];
while (pos < length)
{
if (pos + SplitSize > length)
{
bytes = new byte[length - pos];
}
len = Convert.ToDouble(length);
bytes = b.ReadBytes(bytes.Length);
FileContentMesssage fileContentMesssage = new FileContentMesssage();
fileContentMesssage.Content = bytes;
fileContentMesssage.ReferenceId = ReferenceId;
pos += SplitSize;
fileContentMesssage.SequenceNo = pos / SplitSize;
_totalsequence++;
byte[] filebytes = fileContentMesssage.GetBytes();
FileList.Add(filebytes);
}
}
}
public async void Send()
{
_worker.RunWorkerAsync();
}
public void FileReceive(byte[] bytes)
{
try
{
if (_binaryWriter != null)
_binaryWriter.Write(bytes);
}
catch (Exception ex)
{
}
}
public string FileCreate()
{
string path = AppDomain.CurrentDomain.BaseDirectory;
string filename = Path.GetFileName(FileName);
string fullfilename = string.Format("{0}{1}", path, filename);
_binaryWriter = new BinaryWriter(File.Open(fullfilename, FileMode.Create));
return (fullfilename);
}
public void FileClose()
{
_binaryWriter.Close();
}
public byte[] FileSend()
{
byte[] bytess = FileList[FileSendCount];
FileSendCount++;
return (bytess);
}
public void FileClosed()
{
FileSendCount = 0;
FileList.Clear();
post = 0;
sendlen = 0;
calculate = 0;
totallength = 0;
_totalsequence = 0;
}
}

Thread's response time is very much(not usual)

i want to download a file in C# using a thread in a windows form app,thread works fine at first(for 5 seconds) but suddenly it leaves it work and not respond sometimes for about 10 seconds then it returns a second and then not respond
i am using a class for downloading file
here is the code:
class DownloadFile
{
#region Fields
static Double totalsize;
Double received;
int PartNum;
long start, end;
string savepath;
HttpWebRequest request;
Stream stream;
#endregion
#region Constructors
public DownloadFile() { totalsize = 1; received = 0; }
public DownloadFile(long s, long e, string PATH, HttpWebRequest REQUEST, int Partnumber)
{
totalsize = 1;
PartNum = Partnumber;
received = 0;
start = s;
request = REQUEST;
end = e;
savepath = PATH;
}
#endregion
#region Methods
public void DownLoad()
{
int bytesRead = 0;
byte[] buffer = new byte[1024];
FileStream fstr = new FileStream(savepath + "Part_" + PartNum + Path.GetExtension(Request.RequestUri.ToString()), FileMode.Create, FileAccess.Write);
HttpWebResponse response;
this.request.AddRange(start, end);
response = (HttpWebResponse)this.Request.GetResponse();
stream = response.GetResponseStream();
totalsize = this.end;
bytesRead = stream.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
received += bytesRead;
fstr.Write(buffer, 0, bytesRead);
bytesRead = stream.Read(buffer, 0, buffer.Length);
}
fstr.Close();
stream.Close();
}
public void AppendFiles()
{
}
#endregion
#region properties
public long End
{
get { return end; }
set { end = value; }
}
public long Start
{
get { return start; }
set { start = value; }
}
public Double Received
{
get { return received; }
}
public Double Totalsize
{
get { return totalsize; }
}
public HttpWebRequest Request
{
get { return request; }
set { request = value; }
}
public string SavePath
{
get { return savepath; }
set { savepath = value; }
}
#endregion
}
and here is where thread starts:
Class Program{
List<DownloadFile> DownLoadList = new List<DownloadFile>();
public void DownloadMethod()
{
for (int i = 0; i < DownLoadList.Count; i++)
{
new Thread(new ThreadStart(DownLoadList.ElementAt(i).DownLoad)).Start();
}
}
}
and also i have a timer that updates the download form(progressBar and labels)

Categories

Resources