C# networking TcpClient - c#

Can someone tell me why "Went Through?" gets printed only when argument to Thread.Sleep is < 110?
Update <7.X.2011 5PM ET>: I think what is happening is that the server end is being saturated with client Write(a)'s which then somehow impacts the ability to send data before the connection is closed. Maybe network read buffer is being filled up?
Whenever the iteration count gets above 165xx, the "Went Through?" is not sent, anytime iteration count is <165xx, the string gets sent. This number is reached at Sleep of 107 and onward. Sleep value of 107 sends the string sometimes, depending on other (OS) threads running in the background.
The iteration value never gets above 165xx, even when Sleep is set to a large value (say 2sec), which leads me to believe the network buffer is full.
static void fClient()
{
int iterations = 0;
TcpClient client = new TcpClient("localhost", 22320);
BinaryReader br = new BinaryReader(client.GetStream());
BinaryWriter bw = new BinaryWriter(client.GetStream());
while (true)
{
try
{
if (client.Available > 0)
{
Console.WriteLine(br.ReadString());
}
else
{
bw.Write("a");
iterations++;
}
}
catch (IOException)
{
Console.WriteLine("EXCEPTION");
//exception always reads: Unable to write....
// (thrown by bw.Write("a"))
// show iterations count
break;
}
}
}
static void Main(string[] args)
{
TcpListener server = new TcpListener(22320);
server.Start();
new Thread(fClient).Start();
Thread.Sleep(200);
TcpClient client = server.AcceptTcpClient();
BinaryWriter binWrite = new BinaryWriter(client.GetStream());
binWrite.Write("Went Through?");
binWrite.Flush();
client.Close();
}

I also think the code is straightforward:) But this one doesn't use Sleep to synchronize threads.
static Semaphore Go = new Semaphore(0, 1);
static void Server()
{
TcpListener server = new TcpListener(22320);
server.Start();
Go.Release();
while (true)
{
TcpClient client = server.AcceptTcpClient();
new Thread((x) => ServerTask(x)).Start(client);
}
}
static void ServerTask(object clnObj)
{
TcpClient client = clnObj as TcpClient;
BinaryReader br = new BinaryReader(client.GetStream());
BinaryWriter bw = new BinaryWriter(client.GetStream());
string s = "FromServer: " + br.ReadString();
bw.Write(s);
client.Close();
}
static void Client(int i)
{
TcpClient client = new TcpClient();
client.Connect("localhost", 22320);
BinaryReader br = new BinaryReader(client.GetStream());
BinaryWriter bw = new BinaryWriter(client.GetStream());
bw.Write(i.ToString());
Console.WriteLine(br.ReadString());
client.Close();
}
static void Main(string[] args)
{
Thread t = new Thread(() => Server());
t.IsBackground = true;
t.Start();
Go.WaitOne();
Console.WriteLine("Server Started....");
Parallel.For(0, 21, (i) => Client(i));
Console.WriteLine("Clients Processed");
Console.ReadLine();
}

I think I finally figured this out.
Two endpoints A and B talking to each other: A <-> B
When A sends a message to B and then closes its TcpClient object, I assumed that the TcpClient.Available property on B will still list that last message from A as received and then BinaryReader.ReadString() would be able to retrieve that message, even though the TCP/IP connection was broken by A.
I observed, that that was not always the case and now I think I understand why.
After A closes connection, if B only does reads from network, then it will be able to grab that last message from A and Available property will reflect that message's presence. But if B does a write to the network, then that write will instantly detect a broken connection and fail any subsequent reads/writes, even if Available property returns >0.
So in fact I did understand Available property correctly, but learned today that there are exceptions, when the property will not behave as expected.
If I'm wrong, please correct me. Now onto changing my app.

Related

How to communicate between two Unity apps with TCP?

Update
I figured out what the problem was. I was trying to move too much data over TCP, and it was causing freeze-ups. For some reason, this wasn't manifesting in the editor...who knows for what reason. If anyone else stumbles upon this problem (in a program like Unity, where functions are looping constantly and data is always being processed), consider that you're moving too much irrelevant data.
Original Post
I've run into quite the problem, and I'm hoping I can receive some guidance.
In short, I'm wondering how to use TCP to communicate two Unity apps over the same computer. I've gotten it functioning in editor, but when both apps are built, communication quickly breaks down.
This is really stumping me, because I don't understand why an app would work in the Editor environment, but not in the official build.
When I use TCP to communicate between two Unity apps (on the same computer), it works so long as one of them is kept in the Unity environment. That is, if I build one app, and open the other in the Unity editor, TCP communication works flawlessly.
Here is some more background: One of my apps is functioning as a User Interface, and the other is interfacing with a Looking Glass to provide a holographic display of in-game objects. Originally, they were combined into one App - but I had a lot of trouble getting Unity's multidisplay support to function between two monitors of different resolutions. Looking Glass factory even provides a prefab to do just this, but it is broken in the current SDK. So I have resorted to using sockets to interface between two apps, one for each monitor.
I'm using C#'s TCP listener class: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcplistener?view=netframework-4.8
And TCP client class: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient?view=netframework-4.8
Presently, the UI is acting as the TCPListener, and the application that produces holograms is the TCPClient. Within each of these applications, I'm using two Queues - an IncomingMessages queue and an Outgoing Messages queue - which are global variables shared between the main thread and the networking thread.
TCP Listener:
private void Start()
{
incomingMessages = new Queue();
outgoingMessages = new Queue();
Application.runInBackground = true;
thread = new Thread(new ThreadStart(Receive));
thread.Start();
//stuff happens that's irrelevant to this question. And then...
}
void Receive()
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
Debug.Log("About to reenter main while in Server...");
while (threadContinue)
{
Debug.Log("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Debug.Log("Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Debug.Log("Received from Client: " + data);
lock (this)
incomingMessages.Enqueue(data);
string response = supplyData();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(response);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Debug.Log("Sent to Client: " + response);
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Debug.Log("SocketException: ");
Debug.Log(e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Debug.Log("Exiting 'Receive'");
}
And here is the TCP Client. It attempts to connect a regular intervals, and also whenever new data is available. This is so that it can receive information from the server regularly and share new data whenever it is available:
void Start()
{
//prepare networking
Application.runInBackground = true;
outgoingMessages = new Queue();
incomingMessages = new Queue();
thread = new Thread(new ThreadStart(Connect));
thread.Start();
//stuff happens that's irrelevant to this question...
}
private void Connect()
{
String server = "127.0.0.1";
Int32 port = 13000;
string message = "";
while (threadContinue == true)
{
if (timeToConnect())
{
lastConnection = ourTime;
if (outgoingMessages.Count > 0)
message = outgoingMessages.Dequeue().ToString();
else
message = "Nothing to report.";
try
{
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
client = new TcpClient(server, port);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Debug.Log("Sent to Server: " + message);
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
lock (this)
incomingMessages.Enqueue(responseData);
Debug.Log("Received from Server: " + responseData);
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
Debug.Log("ArgumentNullException: ");
Debug.Log(e);
outgoingMessages.Enqueue(message);
}
catch (SocketException e)
{
Debug.Log("SocketException: ");
Debug.Log(e);
outgoingMessages.Enqueue(message);
}
}
}
}
private bool timeToConnect()
{
if ((ourTime - lastConnection > NETWORK_DELAY) || (outgoingMessages.Count > 0))
return true;
return false;
}
Instantiated in separate threads so that Unity's main thread can continue unhindered.
Again - it works in Editor, but when I build it, it breaks.
Update
I figured out what the problem was. I was trying to move too much data over TCP, and it was causing freeze-ups. For some reason, this wasn't manifesting in the editor...just in the exported app. Who knows for what reason. If anyone else stumbles upon this problem...where you're bypassing Unity's multidisplay functionality by building multiple apps that communicate over network...consider that you're burdening your queues with too much data.

TCP Client Not Reconnecting After Disconnect

I've made a server and a client. The client should re-attempt to connect to the server if I close the server. I've made it so when the try/catch during waitForCommands fails, it restarts the attemptConnection method in a new thread. The problem I have here is that it simply won't reconnect. As a test, I open my TCP server and the TCP client. The client connects to the server as usual. Then, I close the TCP Server, and the clients spits out this error: 'System.Net.Sockets.SocketException' rapidly, and never connects.
class Program
{
public static TcpClient client = new TcpClient();
public static NetworkStream stream;
public static byte[] readBuffer;
static void Main(string[] args)
{
new Thread(attemptConnection).Start();
}
public static void waitForCommands()
{
while (client.Connected)
{
try
{
readBuffer = new byte[client.ReceiveBufferSize];
int data = stream.Read(readBuffer, 0, readBuffer.Length);
string plainText = Encoding.ASCII.GetString(readBuffer, 0, data);
if (plainText.Contains("mbox"))
{
MessageBox.Show("");
}
}
catch
{
new Thread(attemptConnection).Start();
}
}
}
public static void attemptConnection()
{
while(!client.Connected)
{
try
{
client.Connect("127.0.0.1", 23154);
stream = client.GetStream();
new Thread(waitForCommands).Start();
}
catch(Exception ex)
{
Console.WriteLine(ex.Data);
}
}
}
}
An interesting thing I noticed, is that if I write 'client.Close();' on the server exit event, I get no error messages when the client tries to reconnect. It just shows a blank screen and does nothing
If you'd like to see the code that waits for connections on my server, it's really simple so I'm not sure why this problem is occuring.
public static void waitForConnection()
{
server.Start();
client = server.AcceptTcpClient();
stream = client.GetStream();
f.labelControl1.Text = "Connected";
}
To expand on my comment, I think it's due to the underlying TCP connection (the network stream) not closing automatically.
Try closing the stream manually and see what it does:
client.GetStream().Close();
You could also just close the client which closes the stream for you (see https://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.close.aspx):
client.Close();
And another way to resolve your issue (see https://stackoverflow.com/a/38006848/4408417):
client.Client.Disconnect(true);
I changed client.Connect() to
client = new TcpClient();
client.Connect("127.0.0.1", 23154);
As Jasper recommended in the comments

C# while remote TCP connection

I am trying to have a server allow TCP connections and and echo out any newline delimited messages being sent. I want multiple clients to be able to connect one after another, maintaining the same server socket. Here's my code:
TcpClient client;
while (true) {
Console.Write("Waiting for connection... ");
client = listener.AcceptTcpListener();
nStream = client.GetStream();
sReader = new StreamReader(nStream);
Console.WriteLine("Connected!");
while (client.Connected) {
string line = sReader.ReadLine();
Console.WriteLine(line);
}
Console.WriteLine("#Client Disconnected")
}
Unfortunately, when the remote client disconnects, it never escapes the "while (client.Connected)" loop. Instead I get an infinite write to STDOUT.
Basically, the property that you're using TcpClient.Connection does not do what you think it does. From the MSDN documentation:
http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.connected.aspx
Because the Connected property only reflects the state of the connection as of the most recent operation, you should attempt to send or receive a message to determine the current state. After the message send fails, this property no longer returns true. Note that this behavior is by design. You cannot reliably test the state of the connection because, in the time between the test and a send/receive, the connection could have been lost.
The gist is that the property TcpClient.Connection was not updated after the host disconnected but before your server blocked waiting to read another line from the stream. You need a more reliable way to detect if the connection is active before you block.
Turns out, this question has been asked before. So, I borrowed the answer from here and adapted it to the format that you're using in the OP.
https://stackoverflow.com/a/8631090
static void Main(string[] args)
{
TcpClient client = new TcpClient();
TcpListener listener = new TcpListener(IPAddress.Loopback, 60123);
listener.Start();
while (true)
{
Console.WriteLine("Waiting for connection...");
client = listener.AcceptTcpClient();
Console.WriteLine("Connection found");
StreamReader reader = new StreamReader(client.GetStream());
string line = string.Empty;
while (TestConnection(client))
{
line = reader.ReadLine();
Console.WriteLine(line);
}
Console.WriteLine("Disconnected");
}
}
private static bool TestConnection(TcpClient client)
{
bool sConnected = true;
if (client.Client.Poll(0, SelectMode.SelectRead))
{
if (!client.Connected) sConnected = false;
else
{
byte[] b = new byte[1];
try
{
if (client.Client.Receive(b, SocketFlags.Peek) == 0)
{
// Client disconnected
sConnected = false;
}
}
catch { sConnected = false; }
}
}
return sConnected;
}
This works for me when I test it, and the reason that it works is that you cannot tell if the connection is closed until you attempt to read or write from it. You can do that by blindly trying to read/write and then handling the IO exceptions that come when the socket is closed, or you can do what this tester method is doing and peek to see if the connection is closed.
Hope this helps you
EDIT:
It should be noted that this may or may not be the most efficient way to check if the connection is closed, but it is purely to illustrate that you must check the connection yourself on the server side by reading/writing instead of relying on TcpClient.Connection.
EDIT 2:
My sample doesn't clean up old resources very well, apologies to anyone who had an OCD reaction.

TCPClient not receiving data

I want to use StreamReader and StreamWriter to receive and send data over TCPClient.NetworkStream. The code is depicted below:
Client code:
using (TcpClient client = new TcpClient())
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9001);
client.Connect(localEndPoint);
client.NoDelay = true;
using(NetworkStream stream = client.GetStream())
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.AutoFlush = true;
using (StreamReader reader = new StreamReader(stream))
{
string message = "Client says: Hello";
writer.WriteLine(message);
// If I comment the line below, the server receives the first message
// otherwise it keeps waiting for data
string response = reader.ReadToEnd();
Console.WriteLine(response);
}
;
}
}
}
Note: If I comment the reader.ReadToEnd(); then the server receives the message, otherwise the server keeps waiting for data from the client. Is ReadToEnd the problem?
Server code accepts a connection asynchronously, but handles the data in a synchronous manner:
class Program
{
private static AsyncCallback tcpClientCallback;
static void Main(string[] args){
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"),9001);
TcpListener listener = new TcpListener(localEndPoint);
listener.Start();
tcpClientCallback = new AsyncCallback(ConnectCallback);
AcceptConnectionsAysnc(listener);
Console.WriteLine("Started Aysnc TCP listener, press any key to exit (server is free to do other tasks)");
Console.ReadLine();
}
private static void AcceptConnectionsAysnc(TcpListener listener)
{
listener.BeginAcceptTcpClient(tcpClientCallback, listener);
}
static void ConnectCallback(IAsyncResult result)
{
Console.WriteLine("Received a conenct request");
TcpListener listener = (TcpListener)result.AsyncState;
// We are starting a thread which waits to receive the data
// This is not exactly scalable
Task recieveTask = new Task(() => { HandleRecieve(result, listener); });
recieveTask.Start();
AcceptConnectionsAysnc(listener);
}
// This makes a blocking call - that means until the client is ready to
// send some data the server waits
private static void HandleRecieve(IAsyncResult result, TcpListener listener)
{
Console.WriteLine("Waiting for data");
using (TcpClient client = listener.EndAcceptTcpClient(result))
{
client.NoDelay = true;
using (NetworkStream stream = client.GetStream())
{
using (StreamReader reader = new StreamReader(stream))
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.AutoFlush = true;
Stopwatch watch = new Stopwatch();
watch.Start();
string data = reader.ReadToEnd();
watch.Stop();
Console.WriteLine("Time: " + watch.Elapsed.TotalSeconds);
Console.WriteLine(data);
// Send a response to client
writer.WriteLine("Response: " + data);
}
}
}
}
}
}
A stream doesn't end until it is closed. Currently, both client and server are holding their connections open, and both is trying to read to the end from the other - and when they do, will close themselves. This is a deadlock: neither will ever get to the end, so neither will ever close (which would allow the other to get to the end).
Options:
use raw sockets, and have the client close the outbound stream after sending:
socket.Shutdown(SocketShutdown.Send);
this lets the server read to completion, which lets the server close, which lets the client read to completion; the client can still read from the inbound stream after closing the outbound socket.
use a different termination metaphor than ReadToEnd; for text-based protocols, end-of-line is the most common (so: ReadLine); for binary protocols, a length-prefix of the message is the most common. This allows each end to read the next message, without ever having to read to the end of the stream. In this scenario it would only be a single message, but the strategy still works.
use a different protocol if you find the above tricky; http is good for single request/response operations, and can be handled at the server via HttpListener.
Additionally, I'd be very careful about using ReadToEnd on a server (or even ReadLine) - that could be a good way of locking up threads on the server. If the server needs to cope with high throughput and lots of connections, async-IO based on raw sockets would be preferred.

Manage several/multiple tcp connections

I have a server application and client application with the functionality already working. Let me show you how I connect my client application to my server app:
//SERVER
// instantiate variables such as tempIp, port etc...
// ...
// ...
server = new TcpListener(tempIp, port); //tempIp is the ip address of the server.
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[MaxChunkSize];
String data = null;
// Enter the listening loop.
while (disconect == false)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
client = server.AcceptTcpClient(); // wait until a client get's connected...
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
stream = client.GetStream();
// now that the connection is established start listening though data
// sent through the stream..
int i;
try
{
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
// etc..
....
ok now on the client side lets say I want to establish a connection then send some data through the stream
//Client
client = new TcpClient(serverIP, port);
// Get a client stream for reading and writing.
stream = client.GetStream();
//then if I wish to send the string hello world to the server I would do:
sendString(stream, "Hello world");
protected void sendString(NetworkStream stream, string str)
{
sendBytes(stream, textToBytes(str));
}
protected void sendBytes(NetworkStream stream, Byte[] data)
{
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
}
protected static Byte[] textToBytes(string text)
{
return System.Text.Encoding.ASCII.GetBytes(text);
}
since I am able to send bytes I am able to send files or everything that I want. the technique that I use is that if I send the string file for example to the server then the server will start listening for a file. It will open a stream and write the received bytes to that file. If a different keyword is send the server will start listening on a different method etc..
So when dealing with one server and one client everything works great. Now I want to add more clients and need them to also connect to the server. I know that several connections can be establish on the same port just like we do it with por 80 on websites... I do not know how to manage several connections. so one thing I was thinking was to leave everything as it is. if a connection is established then tell the server to start another thread listening for other connections on the same port. with this technique I will have several threads running plus I just know the basics of multrythreading. If this technique is my best option I will start implementing it. You guys out there are really knowledgeable about all this so it will be nice if someone can point me on the right direction. Or maybe I should listen on several ports. if the server is already connected on port 7777 for example then do not accept connections from that port and start listening on port 7778 for example. I mean there could be so many different ways of achieving what I need and you guys probably know the best way. I just know the basics of networking...
You could use threading:
var client = server.AcceptTcpClient();
var t = new Thread(new ParameterizedThreadStart(AccentClient));
t.Start(client);
The target method would look like this
public void AccentClient(object clientObj)
{
var client = clientObj as TcpClient;
// Do whatever you need to do with the client
}
If you are not familiar with multithreading, it is important you learn at least the basics first.
You could implement a class that encapsulates TCP behavior. Check this class:
public class SimpleListener
{
private System.Net.Sockets.TcpListener _tcpListen;
//declare delegate to handle new connections
public delegate void _new_client(System.Net.Sockets.TcpClient tcpclient);
//declare a clients container (or something like...). OPTION 1
List<System.Net.Sockets.TcpClient> _connected_clients;
//declare an event and event handler (the same for _new_client) for new connections OPTION 2
public event _new_client new_tcp_client;
//public (The list of connected clients).
public List<System.Net.Sockets.TcpClient> ConnectedClients { get { return _connected_clients; } }
public SimpleListener(string ip, int listenport)
{
System.Net.IPAddress ipAd = System.Net.IPAddress.Parse(ip);
_tcpListen = new System.Net.Sockets.TcpListener(new System.Net.IPEndPoint(ipAd,listenport));
_connected_clients = new List<System.Net.Sockets.TcpClient>();
}
//Fire this method to start listening...
public void Listen()
{
_tcpListen.Start();
_set_listen();
}
//... and this method to stop listener and release resources on listener
public void Stop()
{
_tcpListen.Stop();
}
//This method set the socket on listening mode...
private void _set_listen()
{
//Let's do it asynchronously - Set the method callback, with the same definition as delegate _new_client
_tcpListen.BeginAcceptTcpClient(new AsyncCallback(_on_new_client), null);
}
//This is the callback for new clients
private void _on_new_client(IAsyncResult _async_client)
{
try
{
//Lets get the new client...
System.Net.Sockets.TcpClient _tcp_cl = _tcpListen.EndAcceptTcpClient(_async_client);
//Push the new client to the list
_connected_clients.Add(_tcp_cl);
//OPTION 2 : Fire new_tcp_client Event - Suscribers will do some stuff...
if (new_tcp_client != null)
{
new_tcp_client(_tcp_cl);
}
//Set socket on listening mode again... (and wait for new connections, while we can manage the new client connection)
_set_listen();
}
catch (Exception ex)
{
//Do something...or not
}
}
}
You could use this in your code:
//SERVER
// instantiate variables such as tempIp, port etc...
// ...
// ...
SimpleListener server = new SimpleListener(tempIp, port); //tempIp is the ip address of the server.
//add handler for new client connections
server.new_tcp_client += server_new_tcp_client;
// Start listening for client requests.
server.Listen();
.... //No need to loop. The new connection is handled on server_new_tcp_client method
void server_new_tcp_client(System.Net.Sockets.TcpClient tcpclient)
{
// Buffer for reading data
Byte[] bytes = new Byte[MaxChunkSize];
String data = null;
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
System.IO.Stream stream = tcpclient.GetStream();
// now that the connection is established start listening though data
// sent through the stream..
int i;
try
{
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
// etc..
....
}

Categories

Resources