I write this simple code to get data from socket:
private void DataReceive()
{
try
{
byte[] bytes = new byte[1000];
int byteRec;
while (true)
{
while (true)
{
byteRec = handler.Receive(bytes);
if (byteRec > 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, byteRec);
break;
}
}
FillLstMsg(data);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
but i want to get data from HEX format,or i see data in hex format?,how can i do this?
These links might help you out. These show the conversion from Byte to HEX. Even if this may not be exactly what you want, you might get the next step that you are looking for.
Get HEX string
Array conversion to HEX string
Hope this helps.
Related
I recently started to work with TCP in C#. I'm now at the point where I want the client to receive the data sent by the server.
I know that there is no guarantee for the client to receive all data at once. If the size of the data sent is bigger than the buffer's size at the client's side, then the data will be sent in parts. So my question is: how can I store all my received data in a byte array, and then convert it to the actual message when all is received?
I've set the buffer size to 1, so I can see what happens when all sent data doesn't fit in the buffer. Here are my methods in which I call stream.BeginRead() in Client.cs:
// Deliberately setting the buffer size to 1, to simulate what happens when the message doesn't fit in the buffer.
int bufferSize = 1;
byte[] receiveBuffer;
private void ConnectCallback(IAsyncResult result)
{
client.EndConnect(result);
Console.WriteLine("Connected to server.");
stream = client.GetStream();
// At this point, the client is connected, and we're expecting a message: "Welcome!"
receiveBuffer = new byte[bufferSize];
stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, new AsyncCallback(ReadCallback), stream);
}
private void ReadCallback(IAsyncResult result)
{
int bytesLength = stream.EndRead(result);
// Should be "Welcome!". But of course it's "W", because the bufferSize is 1.
string message = Encoding.UTF8.GetString(receiveBuffer, 0, bytesLength);
Console.WriteLine("Received message: {0}", receivedMessage);
// Reset the buffer and begin reading a new message, which will be "e".
// However, I want the whole message ("Welcome!") in one byte array.
receiveBuffer = new byte[bufferSize];
stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, ReadCallback, null);
}
This is the output when sending the message "Welcome!":
Connected to server.
Received message: W
Received message: e
Received message: l
Received message: c
Received message: o
Received message: m
Received message: e
Received message: !
Should I temporary store the data until the whole message has arrived, and then convert that to a string?
Follow up question: What if 2 messages are sent closely after each other, for example Welcome! and then What's your name? How do I distinguish the two messages then?
Should I temporary store the data until the whole message has arrived, and then convert that to a string?
Yes, exactly.
Follow up question: What if 2 messages are sent closely after each other, for example Welcome! and then What's your name? How do I distinguish the two messages then?
The general approach is to send the length of the message before the message itself. That way the receiving end will know when it has received a complete package.
As 500 - Internal Server Error already pointed out, you use a buffer for it. Here is some Code example:
Receiving:
while (true) //you should use a bool variable here to stop this on disconnect.
{
byte[] bytes;
bytes = ReadNBytes(ns, 4);
//read out the length field we know is there, because the server always sends it.
int msgLenth = BitConverter.ToInt32(bytes, 0);
bytes = ReadNBytes(ns, msgLenth);
//working with the buffer...
if (bytes.Length > 0)
{
try
{
//do stuff here. bytes contains your complete message.
}
catch (Exception e) { Log(e.Message); }
}
}
public static byte[] ReadNBytes(NetworkStream stream, int n)
{
byte[] buffer = new byte[n];
try
{
int bytesRead = 0;
int chunk;
while (bytesRead < n)
{
chunk = stream.Read(buffer, (int)bytesRead, buffer.Length - (int)bytesRead);
if (chunk == 0)
{
// error out
Log("Unexpected disconnect");
stream.Close();
}
bytesRead += chunk;
}
}
catch (Exception e) { Log(e.Message); }
return buffer;
}
To send stuff use something linke this:
public static void SendObject(NetworkStream ns, byte[] data)
{
byte[] lengthBuffer = BitConverter.GetBytes(data.Length);
ns.Write(lengthBuffer, 0, lengthBuffer.Length);
ns.Write(data, 0, data.Length);
}
I hope that helped!
I know it sounds simple but I got some trouble with it. I am trying to make a system with a pic Microcontroller (MCU) and an xamarin android app. The sending part from app to the pic MCU is solved but when I want to send data from the MCU to the app it won't go as flaweless. I am using a HC-06 as a bluetooth device for receiving and sending messages.
The code for receiving from the MCU to the app is:
public void beginListenForData()
{
try
{
inStream = btSocket.InputStream;
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
}
Task.Factory.StartNew(() => {
byte[] buffer = new byte[1024];
int bytes;
while (true)
{
try
{
Array.Reverse(buffer, 0, buffer.Length);
bytes = inStream.Read(buffer, 0, buffer.Length);
if (bytes > 0)
{
string valor = Encoding.ASCII.GetString(buffer);
System.Diagnostics.Debug.WriteLine(buffer);
System.Diagnostics.Debug.WriteLine(bytes);
System.Diagnostics.Debug.WriteLine(valor);
if (valor == "D0O")
{
System.Diagnostics.Debug.WriteLine("Vergelijking gelukt!");
break;
}
//Result.Text = Result.Text + "\n" + valor;
}
}
catch (Java.IO.IOException)
{
//Result.Text = string.Empty;
break;
}
}
});
}
As you perhaps could geuss the message I try to sent from the MCU is D0O (valor) when the comparison worked with the incoming message I want to debug write that is was successful with:
System.Diagnostics.Debug.WriteLine("Vergelijking gelukt!");
The next part is for checking what for data is coming in:
System.Diagnostics.Debug.WriteLine(buffer);
System.Diagnostics.Debug.WriteLine(bytes);
System.Diagnostics.Debug.WriteLine(valor);
What I noticed is the strange output (see image):
As you can see the message is cut into 2 parts every time. Does anyone has any idea why and how to solve it?
I did change the array order with:
Array.Reverse(buffer, 0, buffer.Length);
Because I did notice it entered in the wrong order. This did work to put it in the right order.
Little update:
I changed some line of code and it works more "flaweless"
while ((count = inStream.Read(buffer, 0, buffer.Length)) > 0)
But what is strange that the first bit gets sepparated from the rest of the receiving string. I am not sure what causes this problem if anyone has a idea?
Thanks in advance.
I found a solution for the problem I was facing. So I will share my answer and thought process so perhaps other people can use the same.
So what I thought was there is a receiving buffer that saves the incoming char's. If the buffer is read with streamReader.Read it returns an integer of the readed char's. So I made second buffer of the datatype string[].
If the string[0] is empty I would place in my first Char that was read by the streamReader.Read. If the string[0] is NOT empty it means that the first char is already been read so I put the incoming char into string[1]. This means that the message that was split up is now into string[0] and string[1]. So what if I could combine it and save it into a string variable. This was done by: string eindtekst = string.Join("", buf); and this gives me the string in one piece so I can compare it. It is importent to clear the both array's as you're done with the comparing otherwise there would be new data added. And as you perhaps can tell string[0] == null would never be true. So only string[1] get's overridden al the time and that means you're losing out on data.
public void beginListenForData()
{
try
{
inStream = btSocket.InputStream;
streamReader = new StreamReader(inStream);
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
}
char[] buffer = new char[256];
string[] buf = new string[2];
int bytes;
while (1)
{
try
{
if ((bytes = streamReader.Read(buffer, 0, buffer.Length)) > 0)
{
string tekst = new string(buffer, 0, bytes);
if(buf[0] == null)
{
buf[0] = tekst;
}
else
{
buf[1] = tekst;
}
string eindtekst = string.Join("", buf);
if (eindtekst == "D0O")
{
System.Diagnostics.Debug.WriteLine("Vergelijking gelukt!");
System.Diagnostics.Debug.WriteLine(eindtekst);
Array.Clear(buffer, 0, buffer.Length);
Array.Clear(buf, 0, buf.Length);
writeData("D2O");
}
streamReader.DiscardBufferedData();
}
}
catch (Java.IO.IOException)
{
break;
}
}
}
Thanks for all the help
Currently I am working on a little project which should work over the network. But I have a problem with a read method, which should read bytes from a network stream. The function reads each single bytes and when it comes to a specific byte(in my case it is ! = 33) it fires an data received event. However when the server sends several messages in a short time the read method misses some messages. Here my code:
public void Read()
{
while (this.isReading == true)
{
try
{
if (!this.stream.DataAvailable)
{
Thread.Sleep(10);
continue;
}
List<byte> receivedBytes = new List<byte>();
byte[] buffer = new byte[1];
while (this.stream.DataAvailable)
{
this.stream.Read(buffer, 0, 1);
// Checks if the current byte is the last byte of a protocol
if (buffer[0] == 33)
{
break;
}
receivedBytes.Add(buffer[0]);
}
this.FireOnDataReceived(receivedBytes.ToArray());
}
catch
{
this.FireOnConnectionLost();
}
}
}
I am making an application where I need to send my phone's accelerometer readings to my Arduino via bluetooth. I am able to send strings easily but, I am getting errors when I am altering the function for integers.
Here is the code I used:
private async void BT2Arduino_Sendint(int value)
{
if (BTSock == null)
{
txtBTStatus.Text = "No connection found. Try again!";
return;
}
else
if (BTSock != null)
{
byte[] buffer = new byte[] { Convert.ToByte(value) };
var datab = GetBufferFromByteArray(UTF8Encoding.UTF8.GetBytes(buffer, 0, 4)); await BTSock.OutputStream.WriteAsync(datab);
txtBTStatus.Text = "Connected to the Device";
}
}
private IBuffer GetBufferFromByteArray(byte[] package)
{
using (DataWriter dw = new DataWriter())
{
dw.WriteBytes(package);
return dw.DetachBuffer();
}
}
The error is basically in the line where I am using UTF8 encoding. It says "The best overloaded method match for System.Text.Encoding.GetBytes(char[], int, int) has some invalid arguments"
Please help me resolve this issue as soon as you can. I know I am doing a mistake with the basics, but I don't have much knowledge with Encoding. Thanks for any help you can provide. :)
Apparently the first parameter of System.Text.Encoding.GetBytes needs to be a char array and not a byte array.
To me looks like you can simply use BitConverter class replacing the code:
if (BTSock != null)
{
byte[] buffer = new byte[] { Convert.ToByte(value) };
var datab = GetBufferFromByteArray(UTF8Encoding.UTF8.GetBytes(buffer, 0, 4));
await BTSock.OutputStream.WriteAsync(datab);
txtBTStatus.Text = "Connected to the Device";
}
with:
if (BTSock != null)
{
byte[] datab = BitConverter.GetBytes(value);
await BTSock.OutputStream.WriteAsync(datab);
txtBTStatus.Text = "Connected to the Device";
}
I want to send a binary file to .net c# component in the following xml format
<BinaryFileString fileType='pdf'>
<!--binary file data string here-->
</BinaryFileString>
In the called component I will use the above xml string and convert the binary string received within the BinaryFileString tag, into a file as specified by the filetype='' attribute. The file type could be doc/pdf/xls/rtf
I have the code in the calling application to get out the bytes from the file to be sent. How do I prepare it to be sent with xml tags wrapped around it? I want the application to send out a string to the component and not a byte stream. This is because there is no way I can decipher the file type [pdf/doc/xls] just by looking at the byte stream. Hence the xml string with the filetype attribute. Any ideas on this?
method for extracting Bytes below
FileStream fs = new FileStream(_filePath, FileMode.Open, FileAccess.Read);
using (Stream input = fs)
{
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{}
}
return buffer;
Thanks.
Edit:
Just to clarify why I am using an xml string rather than setting properties on my component. Actually my calling app is trying to simulate how Siebel will call my component.
http://download.oracle.com/docs/cd/E05553_01/books/eScript/eScript_JSReference244.html#wp1014380
Im not sure if Siebel can set my components properties as I need it to. So Im working on the angle of it sending the data in xml.
Base64 representation is universaly used to represent binary data.
public void EncodeWithString() {
System.IO.FileStream inFile;
byte[] binaryData;
try {
inFile = new System.IO.FileStream(inputFileName,
System.IO.FileMode.Open,
System.IO.FileAccess.Read);
binaryData = new Byte[inFile.Length];
long bytesRead = inFile.Read(binaryData, 0,
(int)inFile.Length);
inFile.Close();
}
catch (System.Exception exp) {
// Error creating stream or reading from it.
System.Console.WriteLine("{0}", exp.Message);
return;
}
// Convert the binary input into Base64 UUEncoded output.
string base64String;
try {
base64String =
System.Convert.ToBase64String(binaryData,
0,
binaryData.Length);
}
catch (System.ArgumentNullException) {
System.Console.WriteLine("Binary data array is null.");
return;
}
// Write the UUEncoded version to the XML file.
System.IO.StreamWriter outFile;
try {
outFile = new System.IO.StreamWriter(outputFileName,
false,
System.Text.Encoding.ASCII);
outFile.Write("<BinaryFileString fileType='pdf'>");
outFile.Write(base64String);
outFile.Write("</BinaryFileString>");
outFile.Close();
}
catch (System.Exception exp) {
// Error creating stream or writing to it.
System.Console.WriteLine("{0}", exp.Message);
}
}
At the receiving end you can reverse this and get back original file content as mentioned below.
// Convert the Base64 UUEncoded input into binary output.
byte[] binaryData;
try {
binaryData =
System.Convert.FromBase64String(base64String);
}
catch (System.ArgumentNullException) {
System.Console.WriteLine("Base 64 string is null.");
return;
}
catch (System.FormatException) {
System.Console.WriteLine("Base 64 string length is not " +
"4 or is not an even multiple of 4." );
return;
}
Can you BASE64 your bytes? MSDN ref: Convert.ToBase64, Convert.FromBase64String
expanding on #russau's answer it will work like this:
var s = "Hello World";
var b = Encoding.Default.GetBytes(s);
var bstr = Convert.ToBase64String(b);
Console.WriteLine("Original String:" + s);
Console.WriteLine("Base64 String:" + bstr);
var fromBStr = Convert.FromBase64String(bstr);
var st = Encoding.Default.GetString(fromBStr);
Console.WriteLine("Converted string: " + st);
you wont need first two lines:
var s = "Hello World";
var b = Encoding.Default.GetBytes(s);
as you already have a byte array. I've used string to show that you get exactly the same value you started with in the end when you convert byte array from Convert.FromBase64String
You mention that you are calling a C# component. I'm not sure I understand why using this component means you need to create an XML string.
Is it possible to define classes to hold your data instead of using an XML string? e.g.
public enum FileType
{
Word,
Excel,
RichText,
PDF
}
public class FileData
{
public FileType TypeOfFile
{
get;
set;
}
public byte[] Data
{
get;
set;
}
}
Then the caller of the component just sets the FileType and the byte[]. The component's interface would then be more explicitly defined (FileData class as opposed to the more generic string or XmlDocument).