Turn over a byte[] from Method A to Method B - c#

I have two methods, prepareData() and sendData():
private void prepareData(string longFileName, string shortFileName)
{
try
{
byte[] fileNameByte = Encoding.ASCII.GetBytes(shortFileName);
byte[] fileData = File.ReadAllBytes(longFileName);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
}
catch
{
}
}
private void sendData(string clientIP, int clientPort, byte[] clientData)
{
TcpClient clientSocket = new TcpClient(clientIP, clientPort);
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Write(clientData, 0, clientData.GetLength(0));
networkStream.Close();
clientSocket.Close();
}
prepareData() is called when the program is loaded; this is a heavy task.
sendData() is called every few seconds and should send the byte[] clientData from prepareData().
How do I get byte[] from the first method to the second?

As have already been stated, the problem is that you're storing clientData in a local variable that is simply thrown away when you exit prepareData. Your clientData must either be stored in a class variable, or returned from prepareData. Try doing something like this:
private byte[] prepareData(string longFileName, string shortFileName)
{
try
{
byte[] fileNameByte = Encoding.ASCII.GetBytes(shortFileName);
byte[] fileData = File.ReadAllBytes(longFileName);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
return clientData;
}
catch
{
}
}
private void sendData(string clientIP, int clientPort, byte[] clientData)
{
TcpClient clientSocket = new TcpClient(clientIP, clientPort);
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Write(clientData, 0, clientData.GetLength(0));
networkStream.Close();
clientSocket.Close();
}
If you do it like this you don't need a timer for the sendData method call; just call it when prepareData has finished, like this:
var clientData = prepareData("longFileName", "shortFileName");
sendData(clientData);
OR
If prepareData really is a heavy task, you should get some threads going and read file blocks in one thread, use a ConcurrentQueue (as suggested by #dweeberly) to store them in, and another thread to call sendData.

I am also not sure what the problem is, but here is how I would solve your problem:
Add this using-directive
using System.Timers;
and in your Class with the prepareData and sendData-Method add a Timer as a field:
private Timer scheduler;
Add a StartSending-Method:
private void StartSending(byte[] clientData) {
double interval = 2000; // 2000ms = 2s
scheduler = new Timer(interval);
scheduler.Elapsed += (sender, e) => {
sendData("someIp", 123, clientData);
};
scheduler.Start();
}
Call this method as soon as your clientData is ready.
Please clarify your problem if that doesn't help you.

I'm guessing you are trying to share data between two methods of your class in a time independent fashion. You need to create a class global structure, based on your example something like:
ConcurrentQueue<byte[]> clientData = new ConcurrentQueue<byte[]>()
Enqueue the data in your prepareData method and TryDequeue the data in sendData

Related

TCP/IP data transfer freezes Unity while transferring the data

I am working on a unity project where user can send data from client to server using TCP/IP. I am able to send the data. But my unity stalls or freeze until the data got read from the networkstream.
Server Code:Read Data.
public void StartServer (){
// Start TcpServer background thread
tcpListenerThread = new Thread (new ThreadStart(ListenForIncomingRequests));
tcpListenerThread.IsBackground = true;
tcpListenerThread.Start();
startServerButton.interactable = false;
path = UnityEditor.EditorUtility.SaveFolderPanel ("Any type of File.", "", ""); // Path.Combine(path,"D:\\Siva\\TCPDownloadfiles");
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Space)) {
SendMessage();
}
}
/// <summary>
/// Runs in background TcpServerThread; Handles incoming TcpClient requests
/// </summary>
private void ListenForIncomingRequests () {
Thread threadForDownloading = new Thread (new ThreadStart(DownloadingStreamData));
threadForDownloading.IsBackground = true;
threadForDownloading.Start();
//DownloadingStreamData ();
}
private void DownloadingStreamData()
{
try {
fileCount++;
int fileNameLen;
byte[] incomingData = new byte[1024];
string ext = "";
// Create listener on localhost port 8052.
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8052);
tcpListener.Start();
Debug.Log("Server is listening");
bytes = new Byte[Int32.MaxValue]; // 2221024
while (true) {
using (connectedTcpClient = tcpListener.AcceptTcpClient()) {
// Get a stream object for reading
using (stream = connectedTcpClient.GetStream()) {
Debug.Log("Befor Stream Read..........");
IAsyncResult result = stream.BeginRead(bytes, 0, bytes.Length, MessageReceived, stream);
result.AsyncWaitHandle.WaitOne();
// Read incoming stream into byte arrary.
do{
//length = stream.Read(bytes, 0, bytes.Length);
//length = s_bytesReceived;
Debug.Log("After Stream Read.........."+length);
incomingData = new byte[length];
Array.Copy(bytes, 0, incomingData, 0, length - 4);
// Convert byte array to string message.
fileNameLen = BitConverter.ToInt32(incomingData, 0);
string clientMessage = Encoding.ASCII.GetString(incomingData,4, fileNameLen);
ext = Path.GetExtension(clientMessage);
//Debug.Log("client message received as: " + clientMessage);
//File.WriteAllBytes(path + "\\temp"+fileCount.ToString()+ext, incomingData);
BinaryWriter bWrite = new BinaryWriter(File.Open(path + "\\temp"+fileCount.ToString()+ext, FileMode.Create)); ;
bWrite.Write(incomingData, 4 + fileNameLen, length - 4 - fileNameLen);
bWrite.Flush();
bWrite.Close();
} while(stream.DataAvailable);
//Debug.Log("Bytes length2 :>>>"+" "+fileNameLen +" Incoming data length" +incomingData.Length);
//connectedTcpClient.Close();
//stream.Flush();
//stream.Close();
//Debug.Log("GETTING FILE NAME THROUGH BUFFER ::"+stream);
}
}
}
}
catch (SocketException socketException) {
Debug.Log("SocketException " + socketException.ToString());
}
}
I tried using stream.BeginRead method but that is throwing exception like Stream/socket was disposed already and trying to access it on client code.
But stream.Read method works as like i expect but it stalls/freeze the unity until it get the data.Please give me some better solution for this issue. Thanks in advance.
Client Code: Sends Data
if (stream.CanWrite) {
string path = UnityEditor.EditorUtility.OpenFilePanel ("Any type of File.", "", "");
WWW www = new WWW ("file:///" + path);
byte[] fileNameBytes = Encoding.ASCII.GetBytes(path);
byte[] fileDataBytes = www.bytes;
byte[] fileNameLength = BitConverter.GetBytes(fileNameBytes.Length);
clientData = new byte[4 + fileNameBytes.Length + fileDataBytes.Length];
fileNameLength.CopyTo(clientData, 0);
fileNameBytes.CopyTo(clientData, 4);
fileDataBytes.CopyTo(clientData, 4 + fileNameBytes.Length);
Debug.Log ("FIle sends to server path : "+path);
//stream.BeginRead(clientData, 0, clientData.Length, MessageReceived, stream);
try {
stream.Write(clientData, 0, clientData.Length);
//stream.BeginWrite(clientData, 0, clientData.Length, MessageReceived, stream);
}catch (Exception e) {
Debug.Log("SocketException " + e.ToString());
}

Arduino ethernet c# client not receiving data

I am having a problem receiving data (a string of text) from an Arduino via a C# Winform app. The sketch on the Arduino basically reply with whatever I send. I am able to send data. What is strange is that if I telnet the device and type any text it responds correctly so it appears the problem is my C# code, however, I can't seem to figure out where I am incorrect.
Here is what I have
public partial class Form1 : Form
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream = default(NetworkStream);
string readData = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox2.Text);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
private void button2_Click(object sender, EventArgs e)
{
clientSocket.Connect("192.168.1.177", 5223);
readData = "Conected Arduino ...";
msg();
serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox2.Text);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Thread ctThread = new Thread(getData);
ctThread.Start();
}
private void getData()
{
while (true)
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = clientSocket.ReceiveBufferSize;
byte[] inStream = new byte[10025];
serverStream.Read(inStream, 0, buffSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
msg();
}
}
}
private void msg()
{
this.BeginInvoke(new Action(() =>
{
textBox1.Text = String.Format("{0}{1} >> {2}", textBox1.Text, Environment.NewLine, readData);
}
));
}
}
Here is part of the Arduino sketch
void loop() {
// wait for a new client:
EthernetClient client = server.available();
// when the client sends the first byte, say hello:
if (client) {
if (!alreadyConnected) {
// clead out the input buffer:
client.flush();
Serial.println("We have a new client");
client.println("Hello, client!");
alreadyConnected = true;
}
if (client.available() > 0) {
// read the bytes incoming from the client:
char thisChar = client.read();
// echo the bytes back to the client:
//server.write(thisChar);
// echo the bytes to the server as well:
//Serial.write(thisChar);
if (inputPos < maxLength-1)
{
if (thisChar == '\n')
{
inputString[inputPos] = 0;
server.write(inputString);
Serial.write(inputString);
inputPos = 0;
} else {
// add it to the inputString:
inputString[inputPos] = thisChar;
inputPos++;
}
} else {
inputPos = 0;
}
}
}
}
Your code has a number of things wrong with it, including what has to be the most common novice error I've seen in any context: you fail to take into account the number of bytes actually read. Plus you have another common variation on the theme, which is that you process the entire receive buffer array as if the whole thing had valid data in it.
Without a way to test, it's hard to know for sure. But at the very least, you should change your receive method to look like this:
private void getData()
{
serverStream = clientSocket.GetStream();
while (true)
{
byte[] inStream = new byte[10025];
int bytesRead = serverStream.Read(inStream, 0, inStream.Length);
readData = System.Text.Encoding.ASCII.GetString(inStream, 0, bytesRead);
msg();
}
}
DON'T pointlessly nest a while (true) loop inside another while (true) loop
DON'T create a new NetworkStream every time you want to read
DON'T concern yourself with the Socket.ReceiveBufferSize property value
DO capture and use the return value from the read operation
DON'T concatenate the empty string with other strings (even in an iterated scenario, one should be using StringBuilder instead, and here you're not even iterating the concatenation!)
Of course, not all of those flaws are fatal. The biggest issues are the new NetworkStream on each read and the mismanagement of the receive buffer and result value. But really, you should strive for all of the code to be good.
Note that the above merely improves the code. Even the above still has a variation on "the most common novice error I've seen in any context": while it does use the return value from the read operation, it does not do everything with it that it should. In particular:
You are not actually guaranteed that you will receive all of the bytes that were sent to you in one read operation. This means your application protocol really should have some way for you to identify within the stream of bytes you're reading where one message ends and the next one starts.
When the connection is gracefully closed, the read operation will return 0 as the byte count, at which point your own code is supposed to respond by finishing up whatever writes to the socket you need to (if any) and then gracefully closing your own socket by calling Socket.Shutdown(SocketShutdown.Both) and finally Socket.Close().
But the above should at least help you make forward progress in your project.
One other thing you really should change IMHO which I didn't bother in the above, is that you should not use an instance field (i.e. readData) to pass data when simply passing it as a method parameter would suffice. You should avoid side-effects in your code as much as possible. It will make the code much easier to comprehend and thus to write correctly, among other things.

Using pipes for IPC in same process using C#

I have two threads. One threads reads requests and passes it to server using message queue and other thread reads the response from message queue and sends it back. In the same process the caller class method writes the request on the pipe (using the server pipe stream shared by first thread) and then reads the response using the client pipe stream shared by the second thread. This can be easily done using Java PipeInputStream and PipeOutputStream as follows. Essentially I am looking for equivalent of following Java logic in C#. I tried unsuccessfully using anonymous pipes in C#.
RequestHandlerThread (Thread1 as mentioned above)
out = new PipedOutputStream();
readPipeIs = new PipedInputStream(out);
readDataIs = new DataInputStream(readPipeIs);
// read data from readDataIs
// Send it to server over message queue
// Share 'out' so that other class method can write to it.
Response Handler (Thread 2 as mentioned above)
in = new PipedInputStream();
writePipeOs = new PipedOutputStream(in);
writeDataOs = new DataOutputStream(writePipeOs);
// Wait and read from message queue
// write received data to 'writeDataOs'
// Share 'in' so that other class method can read from it.
I am not sure if C# pipes are restricted for communicating between two processes. All the above logic is in same process just that there are two threads to communicate with message server.
I tried pair of AnonymousPipeServerStream and AnonymousPipeClientStream pair in both threads. I shared the server stream for writing and client stream for reading by other class method.
Any obvious flaw in above logic or any suggestions with choice of IPC ?
Adding source code
Here is the Test class
class Test
{
private static byte[] ret;
private static bool ready;
Stream outStream;
Stream inStream;
private void clientConnReqHandler()
{
AnonymousPipeServerStream pipeServer = new
AnonymousPipeServerStream(PipeDirection.Out);
outStream = pipeServer;
string pipeHandle =
pipeServer.GetClientHandleAsString();
AnonymousPipeClientStream pipeClient =
new AnonymousPipeClientStream(PipeDirection.In,
pipeHandle);
pipeServer.DisposeLocalCopyOfClientHandle();
ready = false;
BinaryReader binReader = new BinaryReader(pipeClient);
int mesgSize = binReader.ReadInt32();
System.Console.WriteLine("Message Lenght To read: " +
mesgSize);
byte[] buffer = binReader.ReadBytes(mesgSize);
System.Console.WriteLine("Message read: " +
buffer.ToString());
// Simulate some processing
Thread.Sleep(5000);
mesgProcessing(buffer);
}
private static void mesgProcessing(byte[] buffer)
{
System.Text.UTF8Encoding encoding = new
System.Text.UTF8Encoding();
byte[] extra = encoding.GetBytes("Echo : ");
ret = new byte[buffer.Length + extra.Length];
System.Buffer.BlockCopy(extra, 0, ret, 0, extra.Length);
System.Buffer.BlockCopy(buffer, 0, ret, extra.Length,
buffer.Length);
ready = true;
}
private void clientConnRespHandler()
{
AnonymousPipeServerStream pipeServer = new
AnonymousPipeServerStream(PipeDirection.Out);
string pipeHandle =
pipeServer.GetClientHandleAsString();
AnonymousPipeClientStream pipeClient =
new AnonymousPipeClientStream(PipeDirection.In,
pipeHandle);
inStream = pipeClient;
pipeServer.DisposeLocalCopyOfClientHandle();
while (ready)
{
BinaryWriter binWriter = new
BinaryWriter(pipeServer);
binWriter.Write(ret.Length);
binWriter.Write(ret);
ready = false;
}
}
public static void Main()
{
Test setup = new Test();
setup.threadTest();
Test2 threadTest = new Test2();
// This method will do actuall read and write.
threadTest.runTest(setup.inStream, setup.outStream);
}
public void threadTest()
{
Thread reqHandlerThread = new Thread(new
ThreadStart(clientConnReqHandler));
Thread respHandlerThread = new Thread(new
ThreadStart(clientConnRespHandler));
reqHandlerThread.Start();
respHandlerThread.Start();
}
}
The class that does read/write:
class Test2
{
internal void runTest(System.IO.Stream inStream,
System.IO.Stream outStream)
{
BinaryWriter writer = new BinaryWriter(outStream);
System.Text.UTF8Encoding encoding = new
System.Text.UTF8Encoding();
byte[] mesg = encoding.GetBytes("Hello World!!!");
writer.Write(mesg.Length);
writer.Write(mesg);
BinaryReader reader = new BinaryReader(inStream);
int mesgSize = reader.ReadInt32();
System.Console.WriteLine("Message Lenght To read: " +
mesgSize);
byte[] buffer = reader.ReadBytes(mesgSize);
System.Console.WriteLine("Message read: " +
buffer.ToString());
}
}
thanks
OK. It worked after getting rid of DisposeLocalCopyOfClientHandle(). Of course had to fix some new-by mistakes of while loop condition to check if the data is ready and printing the string correctly from byte array.

High CPU % when using delegate

I'm running the following piece of code which uses a delegate to return an asynchronous Network Stream:
static void Main(string[] args)
{
NetworkStream myNetworkStream;
Socket socket;
IPEndPoint maxPort = new IPEndPoint(IPAddress.Parse("xxx.xxx.xxx.xxx"), xxxx);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
socket.Connect(maxPort);
myNetworkStream = new NetworkStream(socket);
byte[] buffer = new byte[1024];
int offset = 0;
int count = 1024;
string Command = "LOGIN,,,xxxx\n";
ASCIIEncoding encoder = new ASCIIEncoding();
myNetworkStream.BeginRead(buffer, offset, count, new AsyncCallback(OnBeginRead), myNetworkStream);
myNetworkStream.Write(encoder.GetBytes(Command), 0, encoder.GetByteCount(Command));
while (true) { }
}
public static void OnBeginRead(IAsyncResult ar)
{
NetworkStream ns = (NetworkStream)ar.AsyncState;
int bufferSize = 1024;
byte[] received = new byte[bufferSize];
ns.EndRead(ar);
int read;
while (true)
{
if (ns.DataAvailable)
{
string result = String.Empty;
read = ns.Read(received, 0, bufferSize);
result += Encoding.ASCII.GetString(received);
received = new byte[bufferSize];
result = result.Replace(" ", "");
result = result.Replace("\0", "");
result = result.Replace("\r\n", ",");
Console.WriteLine(result);
}
}
}
It works, but my CPU usage is through the roof (50% on an Intel Core i3), so obviously I'm doing it wrong, but how so?
Thanks
You're only reading the very first bytes asynchronously, afterwards you end up in an infinite loop with sync read operations in your OnBeginRead method (which is a confusing name BTW). At the same time, those first bytes are discarded in your current code.
You need to process the data after EndRead (which is a function returning how many bytes were read into the buffer in this async operation), and then start another async read with BeginRead and return (there is no looping in the async code!).
Edited to add a sample showing how async reading would work:
internal class StreamHelper {
private readonly NetworkStream stream;
private readonly byte[] buffer = new byte[1024];
public StreamHelper(Socket socket) {
stream = new NetworkStream(socket);
}
public NetworkStream Stream {
get {
return stream;
}
}
public byte[] Buffer {
get {
return buffer;
}
}
}
private static void Main(string[] args) {
IPEndPoint maxPort = new IPEndPoint(IPAddress.Parse("xxx.xxx.xxx.xxx"), 100);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
socket.Connect(maxPort);
StreamHelper helper = new StreamHelper(socket);
helper.Stream.BeginRead(helper.Buffer, 0, helper.Buffer.Length, StreamReadCallback, helper);
string Command = "LOGIN,,,xxxx\n";
byte[] bytes = Encoding.ASCII.GetBytes(Command);
// note: the write isn't async, but should maybe be converted as well
helper.Stream.Write(bytes, 0, bytes.Length);
Console.ReadLine(); // wait for a return key press
}
private static void StreamReadCallback(IAsyncResult ar) {
StreamHelper helper = (StreamHelper)ar.AsyncState;
// note: EndRead will throw an exception if something went wrong - you should deal with that
int bytesRead = helper.Stream.EndRead(ar);
if (bytesRead > 0) {
string charsRead = Encoding.ASCII.GetString(helper.Buffer, 0, bytesRead);
Console.Write(charsRead);
helper.Stream.BeginRead(helper.Buffer, 0, helper.Buffer.Length, StreamReadCallback, helper);
}
}
You are looping continuously on the main thread:
while (true) { }
This causes the CPU core of that thread to be at full capacity at all times. Try to sleep in order to prevent the thread from taking up CPU time unnecessarily:
while (true) { Thread.Sleep(5000); }
Perhaps replace the inefficiency of spinning the processor at the bottom of your main method from
while (true) { }
to
Console.ReadLine();
Incidentally Lucero is spot on. You're moving into an infinte loop (in OnBeginRead) with the thread that calls the callback method. This feels wrong. Callbacks should be dealt with asap to let the calling thread carry on processing. Normally you would extract the data in the callback and post a signal to your own thread to process the rest. Perhaps a TPL thread will help here.

How do i judge when the NetWorkStream finishes by using .net TcpClient to communicate

I try to use stream.DataAvailable to judge if it is finished,but sometimes the value is false but after a little while it is true again,i have to set a counter and judge the end by the symbol '>' like this
int connectCounter = 0;
while (connectCounter < 1200)
{
if (stream.DataAvailable)
{
while (stream.DataAvailable)
{
byte[] buffer = new byte[bufferSize];
int flag = stream.Read(buffer, 0, buffer.Length);
string strReadXML_t = System.Text.Encoding.Default.GetString(buffer);
strReadXML = strReadXML + strReadXML_t.Replace("\0", string.Empty);
}
if (strReadXML.Substring(strReadXML.Length - 1, 1).Equals(">"))
{
break;
}
}
Thread.Sleep(100);
connectCounter++;
}
is there any good methord to deal with it?Thank you!
You have a couple options. You can use a synchronous, blocking Read, or you can use an asynchronous IO pattern.
If you simply call stream.Read(), the call will block, and wait forever (until the TCP timeout), until data is available. It seems you don't want to do that. You want to wait, at most, 120 seconds (1200ms * 100), for the data to be completely read.
Something like this:
private class AsyncState
{
public NetworkStream ns;
public ManualResetEvent e;
public byte[] b;
public String strReadXML;
}
public void Run()
{
TcpClient client ;//= ...
NetworkStream networkStream = client.GetStream();
byte[] buffer = new byte[1024];
var completedEvent = new ManualResetEvent(false);
networkStream.BeginRead(buffer, 0, buffer.Length,
AsyncRead,
new AsyncState
{
b = buffer,
ns = networkStream,
e = completedEvent,
strReadXML = ""
});
// do other stuff here. ...
// finally, wait 120s for the reading to complete
bool success = completedEvent.WaitOne(1200*100, false);
if (!success)
{
client.Close();
}
}
private void AsyncRead(IAsyncResult ar)
{
AsyncState state = ar as AsyncState;
int n = state.ns.EndRead(ar);
if (n == 0)
{
// no more bytes to read
// signal completion
state.e.Set();
return;
}
// state.buffer now contains the bytes read
string s = System.Text.Encoding.Default.GetString(state.b);
state.strReadXML = state.strReadXML + s.Replace("\0", string.Empty);
if (state.strReadXML.EndsWith(">"))
{
// got the "end". signal completion
state.e.Set();
return;
}
// read again
state.ns.BeginRead(state.b, 0, state.b.Length, AsyncRead, state);
}
Try asynchronous reading.
When your callback is called, you can read the existing data buffer and then call
BeginRead again. So that when somre more data is received, you callback will be called again.
Something like:
void DataReceived(IAsyncResult result) ///I am not sure about the parameters.
{
///read data from buffer
networkstream.BeginRead(
buffer, 0, buffer.Length,
new AsyncCallback(DataReceived),
null);
}
I think this is a pretty decent approach.
Do you have control over the sending application? If you do you can change the sending application to wrap the NetworkStream in a BinaryWriter and use .Write( string ) which will send the length of the string, and then the string itself. On the receiving application (as above) you can wrap the NetworkStream in a BinaryReader and call .ReadString() which will read the length from the stream, then read the correct length string in for you.
If you don't have control over the sending application then you can check the return from the stream.Read() call as it returns 0 at the end of the stream - though this will require the sending application to have closed the socket.
Also, stream.Read() is not guaranteed to return the number of bytes you requested, it could return less. Your flag variable should really be bytesread, and you should then pass this bytesread variable to the .GetString method.

Categories

Resources