How to convert back a flattened string to DBL array? - c#

I am trying to send a flatteded DBl array from labview to c# through tcp.
i am receiving the flattened string in c#.
i dont know how to convert them back to DBL array?
This is my code in C#:
{
private TcpClient socketConnection;
private Thread clientReceiveThread;
void Start()
{
ConnectToTcpServer();
}
void Update()
{
}
private void ConnectToTcpServer()
{
try
{
clientReceiveThread = new Thread(new ThreadStart(ListenForData));
clientReceiveThread.IsBackground = true;
clientReceiveThread.Start();
}
catch (Exception e)
{
Debug.Log("On client connect exception " + e);
}
}
private void ListenForData()
{
try
{
socketConnection = new TcpClient("localhost", 5333);
Byte[] bytes = new Byte[4000];
while (true)
{
using (NetworkStream stream = socketConnection.GetStream())
{
int length;
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
{
Debug.Log(bytes.Length);
var incomingData = new byte[length];
Array.Copy(bytes, 0, incomingData, 0, length);
// Convert byte array to string message.
string serverMessage = Encoding.ASCII.GetString(incomingData);
Debug.Log("server message received as: " + serverMessage);
Debug.Log(serverMessage.Length);
}
}
}
}
catch (SocketException socketException)
{
Debug.Log("Socket exception: " + socketException);
}
}
}
This is my labview code:
This is my labview output: (Float array and flattened string)
This is the output in C#:

Since you wired FALSE to the "prepend array or string size", the only data in the buffer is the flattened doubles themselves. But you need to explicitly set "little endian" in order to talk to C#.
If you make that change in the G code, then this should work:
double[] dblArray = (double[])Array.CreateInstance(typeof(System.Double), length / 8);
// I'm not sure if you need the cast or not.
You have the constant "4000" in your code. I would change that to a declared constant and put a comment next to it that says, "Make sure this is a multiple of 8 (number of bytes in double data type)."

Related

How can I handle timeout when I read from namedpipeServerStream?

I have a namedpipeServerStream and I want to stop Reading its pipe when I meet the timeout.
these are my Read and Read callback function , and I call Read in my main program loop repeatedly,
Actually my question is how can I call my callback function manually(or any other way)when timeout happened for endread.
private void Read()
{
tmpBuff = new byte[600];
inRead = true;
ReadTimer.Enabled = true;
len = 0;
try
{
_namedpipeserver.BeginRead(tmpBuff, 0, 600, ReadCallback, null);
}
catch (Exception ex) //disconnected/disposed
{
return;
}
}
static void ReadCallback(IAsyncResult ar)
{
int readbyte;
try
{
readbyte = _namedpipeserver.EndRead(ar);
if (readbyte > 0)
{
len = readbyte;
int packetLen = tmpBuff[0] + (tmpBuff[1] * 256);
Console.WriteLine(" packet len: " + packetLen + " bytes ");
readbyte = 0;
array = null;
array = new byte[packetLen];
Array.Copy(tmpBuff, 2, array, 0, packetLen);
}
}
catch (IOException) //closed
{
return;
}
inRead = false;
}
Any help Appreciated.Thanks
I resolved this problem by disposing connection after a defined timeout and waiting for other side of the pipe to connect again.
Task.Run(() =>
{
tmpBuff = new byte[600];
readbyte = _namedpipeserver.Read(tmpBuff, 0, 600);
}).Wait(10000);
if (readbyte <= 0)
return null;
In case null returned try to reinitiate pipe.

Sending multiple files from C# to C

I have a wpf gui that I want to upload files from and send to a C client .
I want to send 3 files and for some reason 1 of them is being sent and written (but it adds 8 nulls in the end and removes 4 of the first letters in the file)
and in the other two when I try to receive the size it says their size is 0
I've been stuck on this problem for a while now and i'm becoming depserate as i'm probably missing a small thing , if any of u could give a hand that'll mean a lot ! I really wanna know whats the problem in my code.
I have the files paths in an array and sending it in main like so
C# Main
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555);//switch the port
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(ipPoint);
listenSocket.Listen(1);
Socket clientSocket = listenSocket.Accept();
for (int i = 0; i < 1; i++)
{
SendFile(clientSocket, filePaths[i]);
}
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
SendFile(C# side)
public static void SendFile(Socket clientSocket, string filePath)
{
if (File.Exists(filePath))
{
FileInfo fi = new FileInfo(filePath);
long file_size = fi.Length;
byte[] preBuffer;
using (var memoryStream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(memoryStream))
{
writer.Write(file_size);
}
preBuffer = memoryStream.ToArray();
byte[] fixedBuffer = new byte[4];
Array.Copy(preBuffer, 0, fixedBuffer, 0, 4);
Console.WriteLine(BitConverter.ToString(preBuffer));
Console.WriteLine(BitConverter.ToString(fixedBuffer)); //fixing the problem i had with the converting to array that it added 4 useless zeros.
clientSocket.Send(fixedBuffer); // sending size
}
byte[] data = new Byte[4096];
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
int actualRead;
do
{
actualRead = fs.Read(data, 0, data.Length);
clientSocket.Send(data);
file_size -= actualRead;
} while (file_size - filePath.Length > 0);
}
}
else
{
MessageBox.Show("File for the program is missing! lua/pcap/csv");
}
}
C Receive(built from 3 functions)
/*
============================================
General : function is responsible for receiving a length of data from the client
Parameters : sock - client socket to receive the data from
*buf - holds a pointer to the buffer that needs to update
bufsize - the length of the buffer
Return Value : returns TRUE when the data is read correctly
else, FALSE when there was a socket error or no bytes are received.
============================================
*/
bool recv_raw(SOCKET sock, void* buf, int bufsize)
{
unsigned char* pbuf = (unsigned char*)buf;
while (bufsize > 0) {
int num = recv(sock, pbuf, bufsize, 0);
if (num <= 0) { return false; }
pbuf += num;
bufsize -= num;
}
return true;
}
/*
===================================================
General : receives the length of the file and updates it
Parameters : sock - client socket to receive the data from
*filesize - holds a pointer to the size of the buffer that needs to update
filesize_len - the length of the file size pointer
Return Value : returns TRUE when the size is read correctly
else, FALSE when there was a socket error or no bytes are received.
===================================================
*/
bool recv_file_len(SOCKET sock, long* filesize)
{
if (!recv_raw(sock, filesize, sizeof(*filesize))) { return false; }
return true;
}
/*
================================================== =
General : writes to the lua file the data from the file
that was received in the socket
Parameters : sock - the socket between the client and server
*f - the file to write the data received to
Return Value : returns TRUE when everything was written to the file.
returns FALSE if there's no data received or detected a socket problem.
================================================== =
*/
bool write_data(SOCKET sock, FILE *f)
{
long filesize;//size of address
char buffer[BUFFER_SIZE];
if (!recv_file_len(sock, &filesize)) { return false; }
printf("file size (From C#) : %ld\n", filesize);
int n = recv_raw(sock, buffer, 8); // need to get the size of the name
if (filesize > 0)
{
do {
int num = min(filesize, BUFFER_SIZE);
if (!recv_raw(sock, buffer, num)) {
return false;
}
int offset = 0;
do
{
size_t written = fwrite(&buffer[offset], 1, num - offset, f);
if (written < 1) { return false; }
offset += written;
} while (offset < num);
filesize -= num;
} while (filesize > 0);
}
return true;
}
C Main
FILE* luafhandler = fopen("test.lua", "wb");//the new lua file
if (luafhandler == NULL)
{
fclose(luafhandler);
printf("GUI CONNECT lua file failed to open!\n");
}
FILE* pcapfhandler = fopen("test.pcap", "wb");//the new lua file
if (pcapfhandler == NULL)
{
fclose(pcapfhandler);
printf("GUI CONNECT pcap file failed to open!\n");
}
FILE* csvfhandler = fopen("AlgoTest.csv", "wb");//the new lua file
if (csvfhandler == NULL)
{
fclose(csvfhandler);
printf("GUI CONNECT csv file failed to open!\n");
}
else {
SOCKET sock1 = open_socket(5555, SERVER_IP);
bool check = write_data(sock1, luafhandler);
bool check1 = write_data(sock1, pcapfhandler);
bool check2 = write_data(sock1, csvfhandler);
fclose(luafhandler);
fclose(pcapfhandler);
fclose(csvfhandler);
}

Decoding a primitive serial protocol in c#

I grew up with C in the 80's but a complete beginner in c# and object oriented programming so some of you may have a good laugh at this.
I am trying to write a simple application to decode telemetry data from a lab instrument. I plan to write the final code using Windows Forms for look and feel but I made an experimental implementation of the core mechanics as a console app.
The data stream contain 72 byte messages starting with 0x55 0x2f 0x48, then contains payload data and ends with a checksum. I want to "catch" these messages, discard those with bad checksums and decode parts of the payload for display.
The test app work well but simply prints the incoming data. (Although because of its primitive design it does of course take 0x55 in the payload as the start of a new message)
What would be the best practice here? Should I put a state machine into the event handler for the serial port or have a timer that periodically checks the input buffer? I am actually not even sure how to access to the incoming data "outside" the event handler. Any help or pointers would be much appreciated.
The code of my experimental app is this:
using System;
using System.IO.Ports;
namespace Serial_port_experiment_console
{
class Program
{
static void Main(string[] args)
{
var enable_telemetry = new byte[] { 0x55, 0x92, 4, 0x15 };
var disable_telemetry = new byte[] { 0x55, 0x91, 4, 0x16 };
SerialPort sp = new SerialPort("COM12", 9600, Parity.None, 8, StopBits.One);
sp.Open();
sp.Write(enable_telemetry, 0, enable_telemetry.Length); // Start telemetry
sp.DataReceived += port_OnReceiveData;
Console.ReadLine(); // Wait for keyboard RETURN before closing program
sp.Write(disable_telemetry, 0, disable_telemetry.Length); // Stop telemetry
sp.Close();
}
private static void port_OnReceiveData(object sender, SerialDataReceivedEventArgs e)
{
SerialPort spL = (SerialPort)sender;
byte[] buf = new byte[spL.BytesToRead];
spL.Read(buf, 0, buf.Length);
foreach (Byte b in buf)
{
if (b == 0x55) { Console.WriteLine(); } // Start of a new report
Console.Write(b.ToString("X")); // Write the hex code
}
}
}
}
Some encapsulation would help you - I would separate the logic of the reading from the port from the actual line processing into a couple of classes. Something like this:
static void Main(string[] args)
{
Console.WriteLine("Starting reading data");
var reader = new LinesReader();
Console.WriteLine("Reading data...");
try
{
reader.Start();
Console.ReadKey();
}
finally
{
reader.Stop();
}
foreach (var line in reader.ValidLines)
{
line.DoSomethingWithBytes();
}
Console.ReadKey();
}
internal sealed class LinesReader
{
private static readonly byte[] EnableCode = new byte[] { 0x55, 0x92, 4, 0x15 };
private static readonly byte[] DisableCode = new byte[] { 0x55, 0x91, 4, 0x16 };
private readonly SerialPort sp;
private readonly List<LineInput> lines = new List<LineInput>();
public LinesReader()
{
sp = new SerialPort("COM12", 9600, Parity.None, 8, StopBits.One);
lines.Add(new LineInput());
}
public void Start()
{
sp.DataReceived += DataReceived;
sp.Open();
// Start telemetry
sp.Write(EnableCode, 0, EnableCode.Length);
}
private void DataReceived(object sender, SerialDataReceivedEventArgs e)
{
LineInput current;
byte[] buf = new byte[sp.BytesToRead];
sp.Read(buf, 0, buf.Length);
for (int offset = 0; offset < buf.Length; )
{
current = GetCurrentLine();
offset = current.AddBytes(offset, buf);
}
}
private LineInput GetCurrentLine()
{
if (lines.Count == 0 || lines[lines.Count - 1].IsComplete)
{
var ret = new LineInput();
lines.Add(ret);
Console.WriteLine($"Starting line {lines.Count}");
return ret;
}
return lines[lines.Count - 1];
}
public IEnumerable<LineInput> ValidLines => lines.Where(e => e.IsValid);
public void Stop()
{
// Stop telemetry
sp.Write(DisableCode, 0, DisableCode.Length);
sp.DataReceived -= DataReceived;
sp.Close();
}
}
internal sealed class LineInput
{
private readonly List<byte> bytesInLine = new List<byte>();
public static byte StartCode { get; } = 0x55;
public bool IsComplete { get; private set; }
public void DoSomethingWithBytes()
{
//Here I'm just printing the line.
Console.WriteLine(bytesInLine);
}
public bool IsValid
{
get
{
if (!IsComplete) return false;
//TODO - checksum (return true if checksum correct)
return true;
}
}
/// <summary>
/// Adds bytes until the end of the array or a 0x55 code is read
/// </summary>
/// <param name="bytes"></param>
/// <returns>The new offset to start the next segment at.</returns>
public int AddBytes(int offset, byte[] bytes)
{
int bytePosition = offset;
while (bytePosition < bytes.Length)
{
var currentByte = bytes[bytePosition];
if (currentByte == StartCode)
{
IsComplete = true;
break;
}
bytesInLine.Add(currentByte);
bytePosition++;
}
return bytePosition;
}
}
It probably isn't best practice to put all the logic in the event handler. I would suggest that port_OnReceiveData should only be concerned with extracting the 72 byte message. Then you might have another method (or possibly another class) which accepts this message and parses it and extracts whatever data it contains and then in turn may pass that data to another method or class for further processing or saving to a database etc.
I would start by developing port_OnReceiveData to reliably capture the incoming messages. I think you should check for sequence 0x55 0x2f 0x48 rather than just 0x55. Presumably 0x55 could also appear anywhere in the payload, not just the start. Can you contact the manufacturer of the device (or check their website) for details of the message protocol?
A serial port is a difficult thing to test so the idea would be to limit the amount of code dependent on the SerialPort logic so that you can test the actual code you care about (i.e. the processing of the message) in isolation. For instance, once you have captured a few of the 72 byte messages you can keep them and use them to develop your unit tests and logic for the code that will parse these messages without your PC or Laptop having to be physically connected to the lab device.
Another thing you can do if you really want to test your logic is to create a virtual serial port and transmit known data. This technique can be used to ensure your logic is capturing the message correctly. For instance, I once had to read data from a variety of medical devices including a heart rate monitor. I then had to plot this data on a graph. It is obviously crucial that this be correct. I created a test app that generated known wave patterns: a sin wave, saw tooth wave, flat line etc all of known amplitudes and frequencies. I created a virtual com port pair and my test app sent this test wave form data into the com port using the same serial port message format as the real device and I was able to validate that the data I captured and output on the screen was identical to my known wave forms.
I found the question interesting, so whipped up a quick example of what I'd (somewhat naively, without too much planning) do in this case.
Pretty idiomatic C#. Something (MySerialMessageReader) is responsible for reading the data, and fires off an event with a nicely parsed message for the consumer to react to.
Hope that helps?
public static class Program
{
public static void Main(string[] args)
{
using (var reader = new MySerialMessageReader())
{
reader.MessageReaceived += (s, e) =>
{
// TODO: Process message / react to it. Probably put it in a queue to be processed
Console.WriteLine("Received a new message: " + Encoding.UTF8.GetString(e.Message.Data));
};
Console.WriteLine("Waiting for data from serial port...");
Console.ReadLine();
}
}
}
class MySerialMessageReader : IDisposable
{
private byte[] mBuffer = new byte[72];
private int mReceivedCount = 0;
private bool mIsReadingMessage;
SerialPort mPort = new SerialPort("COM12", 9600, Parity.None);
public event EventHandler<MessageEventArgs> MessageReaceived;
public MySerialMessageReader()
{
}
public void Start()
{
mPort.DataReceived += Port_DataReceived;
mPort.Open();
}
private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (e.EventType == SerialData.Eof)
{
if (mIsReadingMessage && mReceivedCount < Message.MESSAGE_LENGTH)
{
Debug.Fail("Received EOF before an entire message was read.");
return;
}
}
// Put the read buffer into our cached buffer
int n = 0;
while (n < mPort.BytesToRead)
{
var readByte = (byte)mPort.ReadByte();
if (!mIsReadingMessage && readByte == 0x55)
{
mIsReadingMessage = true; // New start of message
}
if (mIsReadingMessage)
{
// We're reading a message, put the message into a temporary buffer
// whilst we read(/wait for) the rest of the message
mBuffer[mReceivedCount++] = (byte)mPort.ReadByte();
}
if (mReceivedCount == Message.MESSAGE_LENGTH)
{
// We've got enough to construct a message
Message m = null;
if (Message.TryParse(mBuffer, ref m))
{
if (this.MessageReaceived != null)
this.MessageReaceived(this, new MessageEventArgs(m));
}
else
{
Console.WriteLine("Invalid message received. Checksum error?");
}
mReceivedCount = 0;
Array.Clear(mBuffer, 0, 72);
}
}
}
public void Dispose()
{
if (mPort != null)
{
mPort.DataReceived -= Port_DataReceived;
mPort.Dispose();
}
}
}
class Message
{
private const int CHECKSUM_LENGTH = 3;
private const int START_INDICATOR_LENGTH = 3;
public const int MESSAGE_LENGTH = 72;
public byte[] Data;
public byte[] Checksum;
private Message(byte[] data, byte[] checkSum)
{
this.Data = data;
this.Checksum = checkSum;
}
public static bool TryParse(byte[] data, ref Message message)
{
if (data.Length != MESSAGE_LENGTH)
return false; // Unexpected message length
if (data[0] != 0x55 || data[1] != 0x2F || data[2] != 0x48)
return false; // Invalid message start
var withotStartIndicator = data.Skip(START_INDICATOR_LENGTH);
var justData = withotStartIndicator.Take(MESSAGE_LENGTH - START_INDICATOR_LENGTH - CHECKSUM_LENGTH).ToArray();
var justChecksum = withotStartIndicator.Skip(justData.Length).ToArray();
// TODO: Insert checksum verification of justChecksum here
// TODO: parse justData into whatever your message look like
message = new Message(justData, justChecksum);
return true;
}
}
class MessageEventArgs : EventArgs
{
public Message Message { get; set; }
public MessageEventArgs(Message m)
{
this.Message = m;
}
}
Edit: You can obviously take this as far as you'd like, with async, queues, and whatever have you. But if you're not reading too much data, it's not such a bad thing to do it all in the event handler (in my opinion).

Stop Thread on Button Click in C#

I want to stop my thread on button click event and As I am new to threads I don't know how can I do this in C#. My application is of TCP Client and I am reading TCP server continuously using this thread
public void ClientReceive()
{
try
{
stream = client.GetStream(); //Gets The Stream of The Connection
new Thread(() => // Thread (like Timer)
//Thread mythread = new Thread(ClientReceive);
{
//MessageBox.Show(stream.Read(datalength, 0, 256).ToString());
//(i = stream.Read(datalength, 0, 256)) != 0
while (i != 1)//Keeps Trying to Receive the Size of the Message or Data
{
// how to make a byte E.X byte[] examlpe = new byte[the size of the byte here] , i used BitConverter.ToInt32(datalength,0) cuz i received the length of the data in byte called datalength :D
// byte[] data = BitConverter.GetBytes(1000); // Creates a Byte for the data to be Received On
byte[] data = new byte[1000];
stream.Read(data, 0, data.Length); //Receives The Real Data not the Size
this.Invoke((MethodInvoker)delegate // To Write the Received data
{
//txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data); // Encoding.Default.GetString(data); Converts Bytes Received to String
DateTime now = DateTime.Now;
//MessageBox.Show(Encoding.Default.GetString(data));
if (Encoding.Default.GetString(data) != "")
{
txtLog.Text += System.Environment.NewLine + now.ToString() + " Received : \r\n" + Encoding.Default.GetString(data) + "\r\n";
}
for (int j = 0; j < txtLog.Lines.Length; j++)
{
if (txtLog.Lines[j].Contains("Received"))
{
this.CheckKeyword(txtLog.Lines[j + 1], Color.Red, 0);
}
if (txtLog.Lines[j].Contains("Sent"))
{
this.CheckKeyword(txtLog.Lines[j + 1], Color.Blue, 0);
}
}
});
}
// mythread.Start();
}).Start(); // Start the Thread
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I recommend you to use Task instead of Thread. Because Aborting a thread is not recommnded and it may affect your data as well.
Eric Lippert explained it very well here.
Here is the code for you:
private CancellationTokenSource tokenSource; //global field
public void ClientReceive()
{
try
{
//initiate CancellationTokenSource
tokenSource = new CancellationTokenSource();
stream = client.GetStream(); //Gets The Stream of The Connection
//start parallel task
Task.Factory.StartNew(() =>
{
//MessageBox.Show(stream.Read(datalength, 0, 256).ToString());
//(i = stream.Read(datalength, 0, 256)) != 0
while (i != 1)//Keeps Trying to Receive the Size of the Message or Data
{
// how to make a byte E.X byte[] examlpe = new byte[the size of the byte here] , i used BitConverter.ToInt32(datalength,0) cuz i received the length of the data in byte called datalength :D
// byte[] data = BitConverter.GetBytes(1000); // Creates a Byte for the data to be Received On
byte[] data = new byte[1000];
stream.Read(data, 0, data.Length); //Receives The Real Data not the Size
this.Invoke((MethodInvoker)delegate // To Write the Received data
{
//txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data); // Encoding.Default.GetString(data); Converts Bytes Received to String
DateTime now = DateTime.Now;
//MessageBox.Show(Encoding.Default.GetString(data));
if (Encoding.Default.GetString(data) != "")
{
txtLog.Text += System.Environment.NewLine + now.ToString() + " Received : \r\n" + Encoding.Default.GetString(data) + "\r\n";
}
for (int j = 0; j < txtLog.Lines.Length; j++)
{
if (txtLog.Lines[j].Contains("Received"))
{
this.CheckKeyword(txtLog.Lines[j + 1], Color.Red, 0);
}
if (txtLog.Lines[j].Contains("Sent"))
{
this.CheckKeyword(txtLog.Lines[j + 1], Color.Blue, 0);
}
}
});
}
}, tokenSource.Token);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
//call this method on cancel button
private void cancelTask()
{
if(tokenSource != null) //check if its even initialized or not
tokenSource.Cancel();
}
If you need more explanation about TPL refer to this article.
Try this:
Thread thread = new Thread(() =>
{
Console.WriteLine("Some actions inside thread");
});
thread.Start();
thread.Abort();
First you need to set your thread to some field and then you can control it as shown in code, Start(),Abort().
If you want Abort() thread from button click event you need to move thread field out of method, that way you can get access from your button click event.
Hope Helps!

How to determine that packet receive is a part of first packet using tcp in C#

i code socket application using blocing socket and use multithreading..my problem is i want to receive two large packet..as we know tcp must be split large data into multiple packet..this the scenario:
i send 6 mb text file and tcp split packet into 2 separate packet
at the same time i send 26 mb video file and tcp also split packet into 2 separate packet
at my application i recive first part of text file let say it 3 mb of 6 mb
and then i receive first part of video let say it 13 mb of 26 mb..
the question is how i know that first packet of text file and first packet of video file is a different data and should handle in different way..(different buffer maybe??)
sorry for my bad english..
thanks in advance..
this some part of my code
ns = client.GetStream();
while (isListen == true && client.Connected)
{
while (!ns.DataAvailable)
{
try
{
Thread.Sleep(1);
}
catch (Exception ex)
{
}
}
data = new byte[client.ReceiveBufferSize];
//client.Client.Receive(data);
int indx = ns.Read(data, 0, data.Length);
string message = Encoding.ASCII.GetString(data, 0, indx);
if (message == GetEnumDescription(TypeData.Disconnect))
{
isListen = false;
server.ClientKeluar = objClient;
if (ClientDisconnected != null)
{
ClientDisconnected(objClient);
}
thisThread.Abort();
Server.kumpulanThread.Remove(thisThread);
Server._serverConnections.Remove(this);
client.Close();
}
else if (message.Contains(GetEnumDescription(TypeData.GetFile)))
{
//jalankan proses pengambilan data
}
else if (message.Contains(GetEnumDescription(TypeData.ByteLength)))
{
string length = message.Substring(6, message.Length - 6);
int len = int.Parse(length);
expectedLength = client.ReceiveBufferSize = len;
data = new byte[len];
}
else if (message.Contains(GetEnumDescription(TypeData.Image)))
{
typeData = "Image";
dat1 = new byte[client.ReceiveBufferSize];
index = 0;
}
else if (message.Contains(GetEnumDescription(TypeData.Video)))
{
typeData = "Video";
dat2 = new byte[client.ReceiveBufferSize];
index = 0;
}
else
{
if (typeData == "Image")
{
expectedLength = expectedLength - message.Length;
if (expectedLength == 0)
{
Array.Copy(data, 0, dat1, index, message.Length);
if (ImageDelivered != null)
{
ImageDelivered(dat1);
}
}
else
{
Array.Copy(data, 0, dat1, index, message.Length);
index = message.Length;
}
}
else if (typeData == "Video")
{
expectedLength = expectedLength - message.Length;
if (expectedLength == 0)
{
Array.Copy(data, 0, dat2, index, message.Length);
if (VideoDelivered != null)
{
VideoDelivered(dat2);
}
}
else
{
Array.Copy(data, 0, dat2, index, message.Length);
index = message.Length;
}
}
else
{
expectedLength = expectedLength - message.Length;
if (expectedLength == 0)
{
dataToWrite = dataToWrite + message;
string text = dataToWrite;
if (MessageDelivered != null)
{
MessageDelivered(text);
}
dataToWrite = "";
}
else
{
dataToWrite += message;
}
}
}
}
may anyone give sample code so i can get inspiration to solve this problem?
TCP protocol take cares of making segments of files and later joining them. You will get complete data in receive.

Categories