NetworkStream in C# Socket programming - c#

I am developing a IOS app in xamrain to communicate with hardware in which application sending the string message to the Hardware and hardware respond the message client reading that message through network-stream. After reading the message from the network-stream client flush the network-stream but old message still remain in network-stream. Plz suggest me the solution if anyone known.
private async Task CommandSendAsync()
{
if (sock.Connected)
{
StreamWriter writer = new StreamWriter(sock.GetStream());
writer.WriteLine("abc");
writer.Flush();
await DataReceivedAsync();
}
else { sock.Connect(192.168.1.1, 8025); }
}
string String = "";
public byte[] ReadJunctionSetting = new byte[1071];
int a = 0;
protected Socket SimNetSocket;
public async Task DataReceivedAsync()
{
try
{
await Task.Delay(2000);
String = "";
var abc = sock.GetStream();
//byte[] bytes = new byte[sock.ReceiveBufferSize];
while ((i = abc.Read(ReadJunctionSetting, 0, ReadJunctionSetting.Length)) != 0)
{
abc.Flush();
for (int j = 0; j < 1071; j++)
{
string c = char.ConvertFromUtf32(ReadJunctionSetting[j]);
String += c;
}
abc.Read(ReadJunctionSetting, 0, ReadJunctionSetting.Length);
break;
}
}
catch
{
}
}

From the .NET docs
The Flush method implements the Stream.Flush method; however, because NetworkStream is not buffered, it has no affect on network streams.
You can also the the released .NET source code for NetworkStream here.
Flush is an empty method.

I see several issues on your code, like #Damien_The_Unbeliever already pointed out. For example please avoid things like this:
string String = "";
Use a more meaningful variable name, like message.
But I think your problem is that you get the stream several times. You get then a new stream that still contains the already handled data.
Try to get the stream once after the connection is established and use than this instance for sending and receiving.

Related

TcpClient.BeginRead works once

This is my client side code. The package is sent and received only once. In this code, I use two TCP and UDP protocols simultaneously on one port. My UDP protocol works very well but my TCP protocol has a problem and only sends and receives packets once.
Thanks in advance for your guidance.
This is my code:
private void TryClientConnectToServerCallback(IAsyncResult result)
{
m_TcpClient.EndConnect(result);
if (!m_TcpClient.Connected)
{
return;
}
else
{
m_MyStream = m_TcpClient.GetStream();
m_MyStream.BeginRead(m_ReceiveBuffer, 0, 4096 * 2,new AsyncCallback(ReceiveDataCallBackTcp), null);
//m_TcpClient.Client.BeginSend(m_ReceiveBuffer, 0, 4096 * 2, SocketFlags.None, ReceiveDataCallBackUdp, null);
m_UdpClient.BeginReceive(ReceiveDataCallBackUdp, null);
print(m_UdpClient.Client.Connected);
}
}
private void ReceiveDataCallBackTcp(IAsyncResult result)
{
try
{
print("Data Received");
int m_ReadBytes = m_MyStream.EndRead(result);
if (m_ReadBytes <= 0)
{
return; //no take any data from client
}
jsonObject = new JsonObject();
byte[] m_NewByte = new byte[m_ReadBytes];
Buffer.BlockCopy(m_ReceiveBuffer, 0, m_NewByte, 0, m_ReadBytes);
string jsonData = DataConverter.ConvertToString(m_ReceiveBuffer);
SendAndReceiveSizeDataLogger(false, m_NewByte, "TCP");
//Console.WriteLine("Data receive form client {0}", jsonData);
jsonObject = JsonConvert.DeserializeObject<JsonObject>(jsonData);
Debug.Log(jsonObject.FunctionName);
if (m_Events.ContainsKey(jsonObject.FunctionName))
{
for (int i = 0; i < m_Events[jsonObject.FunctionName].Count; i++)
{
m_Events[jsonObject.FunctionName][i](jsonObject);
}
}
m_MyStream.BeginRead(m_ReceiveBuffer, 0, 4096 * 2, new AsyncCallback(ReceiveDataCallBackTcp), null);
//m_TcpClient.Client.BeginSend(m_ReceiveBuffer, 0, 4096 * 2, SocketFlags.None, ReceiveDataCallBackUdp, null);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
this code send data for client
public void SendTCP(JsonObject jsonObject)
{
if (!m_Socket.Connected)
{
Console.WriteLine("Failed to send data to server, you are not connected to the server");
return;
}
//convert jsonObject class to jsonObject for send to server
string jsonData = JsonConvert.SerializeObject(jsonObject);
//Console.WriteLine("Data Serialized " + jsonData);
byte[] data = new byte[4096];
//convert data to byte array for send to server
data = DataConverter.ConvertToByteArray(jsonData);
Console.WriteLine("Sent Method " + m_Socket.Client.RemoteEndPoint.ToString());
m_MyStream.BeginWrite(data, 0, jsonData.Length, SendTCPCallBack, null);
#region Data Property
int dataSendSize = 0;
for (int i = 0; i < data.Length; i++)
{
if (data[i] > 0)
{
dataSendSize++;
}
}
//Console.WriteLine("Data size send to client : " + dataSendSize);
#endregion
}
It's unclear what this code is trying to do, but it does have several problems. It's clear it's trying to asynchronously receive and deserialize data from a UDP or TCP client, but it's doing this in a very complicated way.
The only clear thing is that it's using Json.NET, which can't deserialize objects asynchronously.
Simply reading and deserializing a UPD message needs just a few lines :
var result=await udpClient.ReceiveAsync();
var jsonData=Encoding.UTF8.GetString(result.Buffer);
var jsonObject = JsonConvert.DeserializeObject<JsonObject>(jsonData);
TCP doesn't have messages though, it's a continuous stream of bytes. If a connection is only meant to retrieve a single document, we could just read until the stream closes and deserialize the data :
await tcpClient.ConnectAsync(...);
using var stream=tcpClient.GetStream();
//Uses UTF8 by default
using var sr=new StreamReader(stream);
var serializer = new JsonSerializer();
var jsonObject=serializer.Deserialize<JsonObject>(jsonData);
If the server sends multiple JSON documents, we'd need a way to identify them, and deserialize them one by one. A very common way to send multiple documents is to use unindented, single line documents and separate them with a newline, eg:
{"EventId":123,"Category":"Business","Level":"Information"}
{"EventId":123,"Category":"Business","Level":"Information"}
{"EventId":123,"Category":"Business","Level":"Information"}
In this case we can use a StreamReader to read the strings one line at a time and deserialize them:
await tcpClient.ConnectAsync(...);
using var stream=tcpClient.GetStream();
//Uses UTF8 by default
using var sr=new StreamReader(stream);
while(true)
{
var line=await sr.ReadLineAsync();
var jsonObject=JsonConvert.DeserializeObject<JsonObject>(jsonData);
...
}
Full Async with System.Text.Json
.NET Core 3.1 introduced System.Text.Json which is fully asynchronous. The TCP code can be rewritten to use JsonSerializer.DeserializeAsync :
await tcpClient.ConnectAsync(...);
using var utf8Stream=tcpClient.GetStream();
var jsonObject=await JsonSerializer.DeserializeAsync<JsonObject>(utf8Stream);
System.Text.Json works only with UTF-8, which is after all the de-facto standard encoding for all web applications.
No DeserializeAsync overload accepts a string, because there's no IO involved when the string is already in memory. The UDP or streaming JSON code would look similar to JSON.NET :
await tcpClient.ConnectAsync(...);
using var stream=tcpClient.GetStream();
//Uses UTF8 by default
using var sr=new StreamReader(stream);
while(true)
{
var line=await sr.ReadLineAsync();
var jsonObject=JsonSerializer.Deserialize<JsonObject>(jsonData);
...
}

Attempt to ReadAsync from SerialDevice silently crashes app

I have a task that is running continuously reading from a serial port. I don't see any outward reason that this wouldn't work, but I don't discount that I could be missing something obvious.
if (serialPort != null)
{
while (true)
{
Windows.Storage.Streams.Buffer inputBuffer = new Windows.Storage.Streams.Buffer(1024);
Windows.Storage.Streams.Buffer resultBuffer = new Windows.Storage.Streams.Buffer(1024);
using (var childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ReadCancellationTokenSource.Token))
{
var t = serialPort.InputStream.ReadAsync(inputBuffer, inputBuffer.Capacity, InputStreamOptions.Partial).AsTask(ReadCancellationTokenSource.Token);
resultBuffer = (Windows.Storage.Streams.Buffer)await t;
if (resultBuffer.Length > 0)
{
LogDebug(string.Format("Read {0} bytes", resultBuffer.Length));
DataReader dataReader = Windows.Storage.Streams.DataReader.FromBuffer(resultBuffer);
string resultString = dataReader.ReadString(resultBuffer.Length);
OnDataReceived(new DataReceiptEventArgs { Data = resultString });
}
}
await Task.Delay(10);
}
}
The result from this is that it reads correctly on the first iteration, but ReadAsync does not seem to handle no data on the stream gracefully when the next iteration happens and all the data has already been read. I would like the behavior to be that task did not return until data was available. At the very least, I would expect an exception, so I might be able to catch that the read failed.
Instead, the debugger logs a message that my app 'has exited with code -1073741811 (0xc000000d).' which is STATUS_INVALID_PARAMETER.
What am I doing wrong? Or will this really never work?
Edit:
This code produces the same error:
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
LogDebug("Listening...");
while (true)
{
uint ReadBufferLength = 1024;
ReadCancellationTokenSource.Token.ThrowIfCancellationRequested();
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
using (var childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ReadCancellationTokenSource.Token))
{
UInt32 bytesRead = 0;
bytesRead = await dataReaderObject.LoadAsync(ReadBufferLength).AsTask(childCancellationTokenSource.Token);
if (bytesRead > 0)
{
LogDebug(string.Format("Read {0} bytes", bytesRead));
string resultString = dataReaderObject.ReadString(bytesRead);
OnDataReceived(new DataReceiptEventArgs { Data = resultString });
}
}
await Task.Delay(10);
}
}
I think I figured it out.
As well as having a read thread going, I also was writing using a DataWriter. But my write method would dispose of the DataWriter on every write. Instead, I now have that declared as a private member of my serial class, and I instantiate the DataWriter upon connection and dispose of it in my close method.
This seems to keep communication going.
Not sure why this happens though, any explanations are welcome.

Unable to write and read to a network stream at the same time c#

I have a program which uses a TCPClient and Network Stream to recieve messages from an external IP. Messages are constantly being sent and the program translates these messages into a more readable format for the user.
However, the IP needs to recieve a keep alive message every 8 seconds to keep the connection open.
I seem to be having difficulty reading in messages, and writing to the stream at the same time. I was under the impression you could read and write to a stream as long as they were on different threads.
Once the timer has elapsed, and the method to write the keep alive message is called, I get the error: Unable to read data from the transport connection: An established connection was aborted by the software in your host machine. This error occurs when it is trying to read in a byte after the write to stream method has been called.
Below is my code. This is the main:
public MainWindow()
{
InitializeComponent();
client.Connect(address, port);
nwStream = client.GetStream();
System.Timers.Timer newTimer = new System.Timers.Timer(8000);
newTimer.Elapsed += delegate { KeepAlive(nwStream, newTimer); };
newTimer.Start();
Thread t = new Thread(ReadInandOutputToTextBoxIfInvoke);
t.Start();
}
Here is the thread and method which reads from the stream:
private void ReadInandOutputToTextBoxIfInvoke()
{
while (run)
{
string message = "";
int x = 0;
int start = 35;
int messageLength;
int numberOfMessages;
// NetworkStream nwStream = client.GetStream();
try
{
while ((x = nwStream.ReadByte()) != start) { if (x == -1) { continue; } } //if it doesnt begin with # or has gone over then break
//reads in message header which is length then number of messages
messageLength = nwStream.ReadByte();
numberOfMessages = nwStream.ReadByte();
string messageRecieved = new string(readMessage(nwStream, messageLength - 1));
string[] messages = messageRecieved.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < numberOfMessages; i++)
{
string messageToProcess = messages[i];
char messageType = messageToProcess[0];
I removed a chunk of that method which translates the message as it isn't relevent.
This is the code which is called when the timer has elapsed:
private void KeepAlive(NetworkStream Ns, System.Timers.Timer MyTimer)
{
byte[] toSend = new byte[] { 35, 51, 49, 42, 124 };
try
{
for (int i = 0; i < toSend.Length; i++)
{
Ns.WriteByte(toSend[i]);
Ns.Flush();
}
}
catch
{
MyTimer.Close();
}
}
I have now solved my issue. There were two factors preventing the program from working properly.
The error stopped appearing after I had used a lock.
The message I was sending to the device was not in the correct format - it had to be in hex
It now works perfectly. Thank you to everyone who tried to help.

C# good practice waiting for TCP response

While making a c# application for remote controlling cisco routers using TCP, I got the problem of waiting for a response from the router.
For the application I have to connect to a Cisco router using a TCP connection. After the connection has been made a networkstream will push my command to the Cisco router. To let the router process the command, I am using Thread.Sleep. This is not the best solution.
Here is the complete code to get a idea what my program is doing.
string IPAddress = "192.168.1.1";
string message = "show running-config"; // command to run
int bytes;
string response = "";
byte[] responseInBytes = new byte[4096];
var client = new TcpClient();
client.ConnectAsync(IPAddress, 23).Wait(TimeSpan.FromSeconds(2));
if (client.Connected == true)
{
client.ReceiveTimeout = 3;
client.SendTimeout = 3;
byte[] messageInBytes = Encoding.ASCII.GetBytes(message);
NetworkStream stream = client.GetStream();
Console.WriteLine();
stream.Write(messageInBytes, 0, messageInBytes.Count()); //send data to router
Thread.Sleep(50); // temporary way to let the router fill his tcp response
bytes = stream.Read(responseInBytes, 0, responseInBytes.Length);
response = Encoding.ASCII.GetString(responseInBytes, 0, bytes);
return response; //whole command output
}
return null;
What is a good and reliable way to get the full response.
Thanks for any help or command.
More info:
The networksteam is always filled with something, most of the time it is filled with the cisco IOS login page. The biggest problem is to determine when the router is done filling up the response.
The response I most of the time get:
"??\u0001??\u0003??\u0018??\u001f\r\n\r\nUser Access Verification\r\n\r\nUsername: "
The return data will be diffent every time because it will be a result of a cisco command. This can vary from a short string to a very long string.
mrmathijs95 -
When reading from NetworkStream with Stream.Read it not 100% sure that you will read all expected data. Stream.Read can return when only few packet arrived and not waiting for others.
To be sure that you get all data use BinaryReader for reading.
BinaryReader.Read method will block current thread until all expected data arrived
private string GetResponse(string message)
{
const int RESPONSE_LENGTH = 4096;
byte[] messageInBytes = Encoding.ASCII.GetBytes(message);
bool leaveStreamOpen = true;
using(var writer = new BinaryWriter(client.GetStream()))
{
writer.Write(messageInBytes);
}
using(var reader = New BinaryReader(client.GetStream()))
{
byte[] bytes = reader.Read(RESPONSE_LENGTH );
return Encoding.ASCII.GetString(bytes);
}
}
Don't use Thread.Sleep. I would async/await the entire thing, given that you don't always know what the data is based on your recent edit. This is how I would do it (untested):
public class Program
{
// call Foo write with "show running-config"
}
public class Foo
{
private TcpClient _client;
private ConcurrentQueue<string> _responses;
private Task _continualRead;
private CancellationTokenSource _readCancellation;
public Foo()
{
this._responses = new ConcurrentQueue<string>();
this._readCancellation = new CancellationTokenSource();
this._continualRead = Task.Factory.StartNew(this.ContinualReadOperation, this._readCancellation.Token, this._readCancellation.Token);
}
public async Task<bool> Connect(string ip)
{
this._client = new TcpClient
{
ReceiveTimeout = 3, // probably shouldn't be 3ms.
SendTimeout = 3 // ^
};
int timeout = 1000;
return await this.AwaitTimeoutTask(this._client.ConnectAsync(ip, 23), timeout);
}
public async void StreamWrite(string message)
{
var messageBytes = Encoding.ASCII.GetBytes(message);
var stream = this._client.GetStream();
if (await this.AwaitTimeoutTask(stream.WriteAsync(messageBytes, 0, messageBytes.Length), 1000))
{
//write success
}
else
{
//write failure.
}
}
public async void ContinualReadOperation(object state)
{
var token = (CancellationToken)state;
var stream = this._client.GetStream();
var byteBuffer = new byte[4096];
while (!token.IsCancellationRequested)
{
int bytesLastRead = 0;
if (stream.DataAvailable)
{
bytesLastRead = await stream.ReadAsync(byteBuffer, 0, byteBuffer.Length, token);
}
if (bytesLastRead > 0)
{
var response = Encoding.ASCII.GetString(byteBuffer, 0, bytesLastRead);
this._responses.Enqueue(response);
}
}
}
private async Task<bool> AwaitTimeoutTask(Task task, int timeout)
{
return await Task.WhenAny(task, Task.Delay(timeout)) == task;
}
public void GetResponses()
{
//Do a TryDequeue etc... on this._responses.
}
}
I didn't expose the read cancellation publicly, but you could add this method to cancel the read operation:
public void Cancel()
{
this._readCancellation.Cancel();
}
And then dispose of your client and all that fun stuff.
Lastly, because you said there's always data available on the stream, where you're doing the read you may have to do some logic on the number of bytes last read to offset yourself within the stream if the data doesn't clear. You'll know if the responses you're getting is always the same.
This is the working code for me.
It uses the solution of Fabio,
combined with a while loop to check every X miliseconds if the response has changed.
client.ReceiveTimeout = 3;
client.SendTimeout = 3;
byte[] messageInBytes = Encoding.ASCII.GetBytes(message);
NetworkStream stream = client.GetStream();
Console.WriteLine();
using (var writer = new BinaryWriter(client.GetStream(),Encoding.ASCII,true))
{
writer.Write(messageInBytes);
}
using (var reader = new BinaryReader(client.GetStream(),Encoding.ASCII, true))
{
while (itIsTheEnd == false)
{
bytes = reader.Read(responseInBytes, 0, responseInBytes.Count());
if (lastBytesArray == responseInBytes)
{
itIsTheEnd = true;
}
lastBytesArray = responseInBytes;
Thread.Sleep(15);
}
}
response = Encoding.ASCII.GetString(responseInBytes);
Thanks for everyone who suggested a solution.
And thanks to Fabio for the given solution.

To find a particular string using telnet through a server side C# Console

I have written this code to check for a particular string from a file. Right now it checks for the string. But how can I send the reply back saying "it is present" to the client? The server side program should have all the codes. It also accepts multiple clients.
The Procedure of this program is as follows
Basically if a client wants to check if there's a particular string(word) in a file, he connects this code through a port on telnet. He types in the strings he wants to search(on telnet) and send it to the server side. And this server side program checks it for him from the file. And if it is present, it sends a message back to the client saying "The string is present in the file" And if it isn't, It should send a message saying "It is not".
The search string("hello") is in this program. How can I enable the client to search for it from client side(telnet)?
This is where I've come till with a lot of help and tutorials. Can someone please help me?
EDITED - I have changed the code such that it sends a reply back to the client. All I need to know now is, how can I enable the client to search (type the word he wants to search for) through the client side(telnet)? Any help will be really appreciated.
I have updated my code too.
Thank you.
class Program
{
static void Main(string[] args)
{
IPAddress ipad = IPAddress.Parse("127.0.0.1");
TcpListener serversocket = new TcpListener(ipad, 8888);
TcpClient clientsocket = default(TcpClient);
Byte[] bytes = new Byte[256];
serversocket.Start();
Console.WriteLine(">> Server Started");
while(true)
{
clientsocket = serversocket.AcceptTcpClient();
Console.WriteLine("Accepted Connection From Client");
LineMatcher lm = new LineMatcher(clientsocket);
Thread thread = new Thread(new ThreadStart(lm.Run));
thread.Start();
Console.WriteLine("Client connected");
}
Console.WriteLine(" >> exit");
Console.ReadLine();
clientsocket.Close();
serversocket.Stop();
}
}
public class LineMatcher
{
public string fileName = "c:/myfile2.txt";
private TcpClient _client;
public LineMatcher(TcpClient client)
{
_client = client;
}
public void Run()
{
byte[] data = new byte[256];
NetworkStream strm = _client.GetStream();
try
{
using (var r = new StreamReader("c:/myfile2.txt"))
{
string line = "";
bool done = false;
int lineNumber = 0;
String s = r.ReadToEnd();
ASCIIEncoding encoder = new ASCIIEncoding();
while (String.IsNullOrEmpty(s))
{
data = encoder.GetBytes("There is no data in the file.");
Console.WriteLine("There is no data in the file.");
}
if (s.IndexOf("hello", StringComparison.CurrentCultureIgnoreCase) >= 0)
{
data = encoder.GetBytes("It is Present.");
}
else
{
data = encoder.GetBytes("It is not Present");
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
strm.Write(data, 0, data.Length);
strm.Flush();
Console.WriteLine("Closing client");
_client.Close();
}
}
Instead of if (s==null), you should check if the string contains the word. Being very creative, we can check for the word "word" like so: if (s.IndexOf("word") >= 0) which searches for the location of "word" within s and returns the index. In C#, indexes always start at 0. If the string "word" is not contained within your file string, it will return -1. Therefore that if statement will return true if the word is contained, or false if it is not.
Think of if as a statement which takes only one parameter. And that parameter is either true or false. The (s==null) is an expression which returns the value true or false which is then used by the if statement.
However, this will not work, if for instance, the file reads: THIS IS A WORD, because "word" does not equal "WORD". You can get around this by using a case insensitive compare like so:
if(s.IndexOf("word", StringComparison.CurrentCultureIgnoreCase) >= 0) {
// contains "word"
} else {
// does not contain "word"
}
Have a look at the following for reference
http://msdn.microsoft.com/en-us/library/ms228362(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/system.string.aspx
Your client applications will only be able to search once. This is because after you perform the search, you close the connection.
Console.WriteLine("Closing client");
_client.Close();
If you want the connection to stay open you will need to include a loop to ensure you return to the beginning of the LineMatcher class to re-search.
Rather than checking the IndexOf this string, I'd instead simply use the Contains method. While IndexOf is designed to find where a substring is located within a string, Contains is built for the specific purpose of simply checking whether or not a substring exists. Note that this is not case insensitive.
else if (s.Contains("HTTP"))
{
I would strongly recommend you get the searching application working first, as a stand-alone application, and then write a telnet server which launches your original application. These are two separate functions, and you'll find it a lot easier to test them individually.
I solved it. :) This is how I did it. Any suggestions on improving it?
namespace ServerSideApplication
{
class Program
{
static void Main(string[] args)
{
TcpListener socketListener = new TcpListener(8888);
TcpClient netClient = default(TcpClient);
StreamReader sr;
StringBuilder sb = new StringBuilder();
socketListener.Start();
sr = new StreamReader("c:\\test.txt");
sb.Append(sr.ReadToEnd());
while (true)
{
netClient = socketListener.AcceptTcpClient();
Console.WriteLine("Accepted Connection From Client" + Environment.NewLine + "Client connected");
ServerSide ss = new ServerSide();
ss.startServerSide(netClient, sb);
}
socketListener.Stop();
}
}
class ServerSide
{
TcpClient netClient;
StringBuilder sb;
public void startServerSide(TcpClient netClient, StringBuilder sb)
{
this.netClient = netClient;
this.sb = sb;
Thread thread = new Thread(processRequest);
thread.Start();
}
private void processRequest()
{
byte[] data = new byte[4096];
int bytesRead;
NetworkStream strm = netClient.GetStream();
bytesRead = 0;
try
{
NetworkStream ns = netClient.GetStream();
string clientChar = "", s = "";
do
{
bytesRead = ns.Read(data, 0, (int)data.Length);
clientChar = Encoding.ASCII.GetString(data).Replace("\0", "");
s += clientChar;
} while (clientChar != Environment.NewLine);
s = s.Trim();
ASCIIEncoding encoder = new ASCIIEncoding();
if (String.IsNullOrEmpty(s))
{
data = encoder.GetBytes("There is no data in the file.");
Console.WriteLine("There is no data in the file.");
}
if (sb.ToString().Contains(s))
{
data = encoder.GetBytes("It Is Present In The File.");
}
else
{
data = encoder.GetBytes("It Is Not Present In The File.");
}
strm.Write(data, 0, data.Length);
strm.Flush();
Console.WriteLine("Closing client");
netClient.Close();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
}
}
}

Categories

Resources