I am building an FTP server that will get images from a camera and store the photos in a local directory. I am having issues grabbing the file from the port given to me. Here is the conversation:
Server(me):"220 Ready!"
Client:"USER Guest"
Server: "331 Username ok, need password"
Client:"PASS "
Server: "230 user logged in"
Client: "PWD"
Server: "257 \"/\""
Client: "EPRT |1|172.22.22.103|58719|
Server:"500 IDK"
Client: "PORT 172,22,22,103,147,237"
Server:"200 Ready for Transport"
Client: "TYPE I"
Server:"200 I understand it is an image file"
Client: "STOR .TEST.RHPRYI"
I found the port by converting the last two numbers to hexadecimal (93,ED) appending them and then converting back to decimal. My final port is 37869.
I then create a new TcpClient to use as a download, but my TcpListener never picks up the camera. Also I am not sure my download method is correct.
I got lots of my code from here:
http://www.codeproject.com/Articles/380769/Creating-an-FTP-Server-in-Csharp-with-IPv-Support
Really my question comes down to: How do I get the file being sent by the client as an FTP server in C#?
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.Drawing;
using Microsoft.VisualBasic;
//Creates a TcpServer that is used to transfer images from the Axis Camera to a directory on a computer
//ftpdmin was chosen as the name because it was supposed to be a replica of a program in c just made in csharp
//However, it was really hard to transfer from c because all of the struct names and functions were nonintuitive
//This program is completely made from internet sources, and there are definitely bugs. For instance it does not implement
// many FTP calls.
namespace ftpdmin
{
class Server
{
//TCPListener listens to a given IP and port to wait for a connection with the camera
//Download Listener listens to the port given by the camera in the PORT command, which is the
//port at which the files needed to be downloaded are stored.
//Listen thread implements tcpListener. We do not want to be stuck in an infinite loop, but
//we always want to be listening to the camera. That is why we use another thread.
//Downlaod thread implements the downloadlistener for the same reason as above
//File name is the download files name given by the camera in the STOR command.
//direct is the directory to save the files at on the local computer. It was given in the main
// method of the console program. See Program.cs
private TcpListener tcpListener;
private TcpListener downloadListener;
private Thread listenThread;
private Thread downloadThread;
private string fileName;
private string direct;
//Initialize Ip adress and threads
public Server(string dir)
{
direct = dir;
this.tcpListener = new TcpListener(IPAddress.Parse("172.22.22.104"), 3000);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
//Start listening
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void ListenForDownloads()
{
this.downloadThread.Start();
while(true)
{
TcpClient downloadClient = this.downloadListener.AcceptTcpClient();
Thread clientDownloadThread = new Thread(new ParameterizedThreadStart(HandleClientDownload));
clientDownloadThread.Start(downloadClient);
}
}
private void HandleClientDownload(object downloadClient)
{
Console.WriteLine("IM HERE");
TcpClient downloaderClient = (TcpClient) downloadClient;
NetworkStream downloadStream = downloaderClient.GetStream();
StreamWriter downloadWriter = new StreamWriter(downloadStream, Encoding.ASCII);
StreamReader downloadReader = new StreamReader(downloadStream);
try
{
//Sets up the path to store the file
string path = Path.Combine(direct, fileName);
FileStream file = File.Create(path);
//Implements the method to download a file
CopyStream(file, downloadStream);
file.Close();
}
catch (Exception e)
{
Console.WriteLine("a socket error has occured:" + e);
}
}
private void HandleClientComm(object client)
{
//A Server is TCP has to respond to a bunch of commands from the client. The first thing it
//does when it connects is send code 220 which says it is good to continue.
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
StreamWriter writer = new StreamWriter(clientStream, Encoding.ASCII);
StreamReader reader=new StreamReader(clientStream);
writer.WriteLine("220 Ready!");
writer.Flush();
string command=reader.ReadLine().ToUpperInvariant();
int downloadPort=0;
string ipOfDownload="";
Console.WriteLine(command);
while(!command.Equals("QUIT"))
{
//USER comes with the username given to the client. Here I do not check if the cameras username
//is the same as the username in the program. I just give the command 331 which means continue.
if(command.Contains("USER"))
{
writer.WriteLine("331 Username ok, need password");
writer.Flush();
}
//PASS is the same as username. I do not check the passwords, I just give 230 which continues the FTP.
else if(command.Contains("PASS"))
{
writer.WriteLine("230 User Logged In");
writer.Flush();
}
//PWD is Print working directory. I send 257 to say I have a PWD, and I send / because that is what is saved
// in the camera. I am not actually going to save files at this directory, I just want to continue.
else if(command.Contains("PWD"))
{
writer.WriteLine("257 \"/\"");
writer.Flush();
}
//This is an important command. The client is sending an IP where it wants to do file transfers. It comes in a
//Weird format so all this function is doing is allowing me store Ip as "172.22.22.103" instead of "PORT 172,22,22,103"
//Also there is a port listed at the end, but it is given in 2 numbers. The conversion to one port number is done by
//changing the two numbers to hexadecimal, appending them, and then transforming them back to decimal.
else if(command.Contains("PORT"))
{
string portPart1 = "";
string portPart2 = "";
Console.WriteLine(command);
int numberOfCommas=0;
int i=0;
bool notPort=true;
bool isNotPortPart2=true;
while(i<command.Length && notPort)
{
if(command[i].Equals(','))
{
if(numberOfCommas==3)
{
notPort=false;
}
else
{
ipOfDownload+=".";
numberOfCommas++;
}
}
else if(Information.IsNumeric(command[i]))
{
ipOfDownload+=command[i];
}
i++;
}
while(i<command.Length && isNotPortPart2)
{
if(Information.IsNumeric(command[i]))
{
portPart1+=command[i];
}
else
{
isNotPortPart2=false;
}
i++;
}
while(i<command.Length)
{
portPart2+=command[i];
i++;
}
Console.WriteLine("IP=" +ipOfDownload);
Console.WriteLine("PortPart1="+portPart1);
Console.WriteLine("PortPart2="+portPart2);
int portPart1int = int.Parse(portPart1);
int portPart2int = int.Parse(portPart2);
string portPart1Hex = portPart1int.ToString("X");
string portPart2Hex = portPart2int.ToString("X");
string downloadPortHex = portPart1Hex + portPart2Hex;
downloadPort = Convert.ToInt32(downloadPortHex, 16);
Console.WriteLine("PortPart1Hex=" + portPart1Hex);
Console.WriteLine("PortPart2Hex=" + portPart2Hex);
Console.WriteLine("FinalPort: " + downloadPort);
this.downloadListener = new TcpListener(IPAddress.Parse(ipOfDownload), downloadPort);
this.downloadThread = new Thread(new ThreadStart(ListenForDownloads));
writer.WriteLine("200 Ready for Transport");
writer.Flush();
}
//The client sends TYPE I for image. usually an ftp would switchto binary mode because that is the only way
//a file can be transferred cleanly.
else if(command.Contains("TYPE"))
{
writer.WriteLine("200 I understand it is an image file");
writer.Flush();
}
//This command gives the name of the file being transferred. I substring to get rid of
//The STOR . that comes before the file name
else if(command.Contains("STOR"))
{
fileName = command.Substring(6);
Console.WriteLine(fileName);
}
//For all other commands sent by the client, I send 500 which means I'm not implementing those commands.
else
{
writer.WriteLine("500 IDK");
writer.Flush();
}
command=reader.ReadLine().ToUpperInvariant();
Console.WriteLine(command);
}
writer.WriteLine("221 BYE");
writer.Flush();
tcpClient.Close();
}
private static long CopyStream(Stream input, Stream output, int bufferSize)
{
byte[] buffer = new byte[bufferSize];
int count = 0;
long total = 0;
while ((count = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, count);
total += count;
}
return total;
}
private static long CopyStreamAscii(Stream input, Stream output, int bufferSize)
{
char[] buffer = new char[bufferSize];
int count = 0;
long total = 0;
using (StreamReader rdr = new StreamReader(input))
{
using (StreamWriter wtr = new StreamWriter(output, Encoding.ASCII))
{
while ((count = rdr.Read(buffer, 0, buffer.Length)) > 0)
{
wtr.Write(buffer, 0, count);
total += count;
}
}
}
return total;
}
private long CopyStream(Stream input, Stream output)
{
//if (_transferType == "I")
//{
return CopyStream(input, output, 4096);
//}
//else
//{
// return CopyStreamAscii(input, output, 4096);
//}
}
}
By the ERTP (or PORT) command, the client tells your server where the client is listening for incoming transfer connections to be initiated by the server. Instead you start listening too. So both parties are listening and nothing can happen.
So instead of TcpListener, you need to create TcpClient and actively connect.
See RFC 2428.
What you have implemented resembles passive mode (EPSV or PASV command), while the client is using an active mode.
Anyway you should better use an existing implementation of FTP server instead of trying to implement your own.
Related
I am obviously new to TCP servers.
The code below works just fine - It "only" echoes the messages it receives.
But my question is "simple": How can I send responses to my client - other than simply echoing the request as I do below?
For instance, if I wanted to send data back (specifically for me, "OFML" data in XML like form for criminal justice end-users).
But I'd settle for "Hello world!"!
All my attempts to do this result in my client crashing (the proprietary code of which I cannot share) - and some customized error messages like, "NO Packet Found".
Any suggestions would be most appreciated - or references to some clear documentation on how to accomplish this.
Oh - and I might add I am simply trying to create a simple "mock" server for local debugging of the client - i.e this will never be for "production".
Thanks!
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Threading;
namespace FoxTalkMOCK
{
class Program
{
public static void Main()
{
TcpListener server = null;
try
{
Int32 port = 8080;
IPAddress localAddr = IPAddress.Parse("10.116.45.49");
server = new TcpListener(localAddr, port);
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[18];
String data = null;
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("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.
try
{
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);
// Process the data sent by the client.
data = data.ToUpper();
string bitString = BitConverter.ToString(bytes);
bitString = bitString.Replace("-", ", 0x");
bitString = "0x" + bitString;
Console.WriteLine(bitString);
// *******************Send response*********************
stream.Write(bytes, 0, bytes.Length);
Console.WriteLine("Sent: {0}", System.Text.Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
}
}```
The example connects and receives data, then sends that data back and disconnects.
If you want to keep the socket, keep it without breaking.
Whenever you save it and write it again, you can manage whether the socket is maintained through exception handling.
The answer to simply returning a "hello world" is as follows:
var strBuffer = "Hello World!";
byte[] array = new byte[strBuffer.Length];
array = System.Text.Encoding.ASCII.GetBytes(strBuffer);
stream.Write(array, 0, array.Length)
I'm implementing an application in .Net. I have to create a connection by SSH which is works, but the HL7 data receiving fails. The destination is a raspberry pi. So when I'm debugging the ssh client is connected, the port is forwarded, the tcp client also connected, but there is no answer for my queries. Plese suggest me some examples!
In this project I have already implemented it on Android - it works fine.
So in .Net I tried the NHapiTools library and I also tried the direct TcpClient way too. localPort = remotePort. I used localIP = "localhost"
static void Main(string[] args)
{
try
{
PrivateKeyFile file = new PrivateKeyFile(#"./key/private.key");
using (var client = new SshClient(remoteIP, sshPort, username, file))
{
client.Connect();
var ci = client.ConnectionInfo;
var port = new ForwardedPortLocal(localIP, localPort, client.ConnectionInfo.Host, remotePort);
client.AddForwardedPort(port);
port.Start();
var req = "MSH|^~\\&|TestAppName||AVR||20181107201939.357+0000||QRY^R02^QRY_R02|923456|P|2.5";
////TCP
var tcpClient = new TcpClient();
tcpClient.Connect(localIP, (int)localPort);
Byte[] data = System.Text.Encoding.ASCII.GetBytes(req);
using (var stream = tcpClient.GetStream())
{
stream.Write(data, 0, data.Length);
using (var buffer = new MemoryStream())
{
byte[] chunk = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(chunk, 0, chunk.Length)) > 0)
{
buffer.Write(chunk, 0, bytesRead);
}
data = buffer.ToArray();
}
}
//I used this also with same result -> no respond
//SimpleMLLP
/*
var connection = new SimpleMLLPClient(localIP, localPort,
Encoding.UTF8);
var response = connection.SendHL7Message(req);
*/
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadLine();
}
}
So I experinced that the buffer size is 0 in TCP (due to time out). In the SimpleMLLP test SendHK7Message method never returns
You are not implementing MLLP (also called LLP) protocol while sending message.
Description HEX ASCII Symbol
Message starting character 0B 11 <VT>
Message ending characters 1C,0D 28,13 <FS>,<CR>
This way, when you send a message to Listener (TCP/MLLP server), it looks for Start Block in your incoming data. It never finds it. It just discards your entire message considering garbage. Hence, you get nothing back from Listener.
With MLLP implemented, your message (the stuff you are writing on socket) should look something like below:
<VT>MSH|^~\\&|TestAppName||AVR||20181107201939.357+0000||QRY^R02^QRY_R02|923456|P|2.5<FS><CR>
Note the <VT>, <CR> and <FS> are place holders in above message.
You may refer to this article for detailed information (Read step 4 and onward):
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace SimpleMllpHl7ClientAdvanced
{
public class Program
{
private static char END_OF_BLOCK = '\u001c';
private static char START_OF_BLOCK = '\u000b';
private static char CARRIAGE_RETURN = (char)13;
static void Main(string[] args)
{
TcpClient ourTcpClient = null;
NetworkStream networkStream = null;
var testHl7MessageToTransmit = new StringBuilder();
//a HL7 test message that is enveloped with MLLP as described in my article
testHl7MessageToTransmit.Append(START_OF_BLOCK)
.Append("MSH|^~\\&|AcmeHIS|StJohn|CATH|StJohn|20061019172719||ORM^O01|MSGID12349876|P|2.3")
.Append(CARRIAGE_RETURN)
.Append("PID|||20301||Durden^Tyler^^^Mr.||19700312|M|||88 Punchward Dr.^^Los Angeles^CA^11221^USA|||||||")
.Append(CARRIAGE_RETURN)
.Append("PV1||O|OP^^||||4652^Paulson^Robert|||OP|||||||||9|||||||||||||||||||||||||20061019172717|20061019172718")
.Append(CARRIAGE_RETURN)
.Append("ORC|NW|20061019172719")
.Append(CARRIAGE_RETURN)
.Append("OBR|1|20061019172719||76770^Ultrasound: retroperitoneal^C4|||12349876")
.Append(CARRIAGE_RETURN)
.Append(END_OF_BLOCK)
.Append(CARRIAGE_RETURN);
try
{
//initiate a TCP client connection to local loopback address at port 1080
ourTcpClient = new TcpClient();
ourTcpClient.Connect(new IPEndPoint(IPAddress.Loopback, 1080));
Console.WriteLine("Connected to server....");
//get the IO stream on this connection to write to
networkStream = ourTcpClient.GetStream();
//use UTF-8 and either 8-bit encoding due to MLLP-related recommendations
var sendMessageByteBuffer = Encoding.UTF8.GetBytes(testHl7MessageToTransmit.ToString());
if (networkStream.CanWrite)
{
//send a message through this connection using the IO stream
networkStream.Write(sendMessageByteBuffer, 0, sendMessageByteBuffer.Length);
Console.WriteLine("Data was sent data to server successfully....");
var receiveMessageByteBuffer = Encoding.UTF8.GetBytes(testHl7MessageToTransmit.ToString());
var bytesReceivedFromServer = networkStream.Read(receiveMessageByteBuffer, 0, receiveMessageByteBuffer.Length);
// Our server for this example has been designed to echo back the message
// keep reading from this stream until the message is echoed back
while (bytesReceivedFromServer > 0)
{
if (networkStream.CanRead)
{
bytesReceivedFromServer = networkStream.Read(receiveMessageByteBuffer, 0, receiveMessageByteBuffer.Length);
if (bytesReceivedFromServer == 0)
{
break;
}
}
}
var receivedMessage = Encoding.UTF8.GetString(receiveMessageByteBuffer);
Console.WriteLine("Received message from server: {0}", receivedMessage);
}
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
catch (Exception ex)
{
//display any exceptions that occur to console
Console.WriteLine(ex.Message);
}
finally
{
//close the IO strem and the TCP connection
networkStream?.Close();
ourTcpClient?.Close();
}
}
}
}
You should modify your following line of code as below:
var req = START_OF_BLOCK + "MSH|^~\\&|TestAppName||AVR||20181107201939.357+0000||QRY^R02^QRY_R02|923456|P|2.5" + END_OF_BLOCK + CARRIAGE_RETURN;
For more open source code, you may refer to this github project.
After days of struggling I have solved the problem. The main error was with the port forwarding.
I would reccomend to use SSH.Net by Renci (There was algorithm error with Tamir ssh).
After ssh connection created I used this to port forward:
var port = new ForwardedPortLocal(localIP, localPort, "localhost", remotePort);
Check your localIP with ipconfig /all in cmd. Or use 127.0.0.1 as a loopback IP.
SimpleMLLPClient did not worked for me so I used the direct tcp client query way. Like this:
TcpClient ourTcpClient = new TcpClient();
ourTcpClient.Connect(localIP, (int)localPort);
NetworkStream networkStream = ourTcpClient.GetStream();
var sendMessageByteBuffer = Encoding.UTF8.GetBytes(testHl7MessageToTransmit.ToString());
if (networkStream.CanWrite)
{
networkStream.Write(sendMessageByteBuffer, 0, sendMessageByteBuffer.Length);
Console.WriteLine("Data was sent to server successfully....");
byte[] receiveMessageByteBuffer = new byte[ourTcpClient.ReceiveBufferSize];
var bytesReceivedFromServer = networkStream.Read(receiveMessageByteBuffer, 0, receiveMessageByteBuffer.Length);
if (bytesReceivedFromServer > 0 && networkStream.CanRead)
{
receivedMessage.Append(Encoding.UTF8.GetString(receiveMessageByteBuffer));
}
var message = receivedMessage.Replace("\0", string.Empty);
Console.WriteLine("Received message from server: {0}", message);
}
So it gave me instant answer with 0 bytes (not due timeout). And here comes Amit Joshi help. I used a query what he suggested with START_OF_BLOCK, CARRIAGE_RETURN and END_OF_BLOCK and finally started to work. Thank you Amit Joshi!
Additional info:
In Android (java/Kotlin) jsch session setPortForwardingL works fine with three params:
val session = jsch.getSession("user", sshIP, sshPort)
session.setPassword("")
jsch.addIdentity(privatekey.getAbsolutePath())
// Avoid asking for key confirmation
val prop = Properties()
prop.setProperty("StrictHostKeyChecking", "no")
session.setConfig(prop)
session.connect(5000)
session.setPortForwardingL(localForwardPort, "localhost", remotePort)
val useTls = false
val context = DefaultHapiContext()
connection = context.newClient("localhost", localForwardPort, useTls)
Currently I am writing a C# program meant to satisfy a Computer Networks class project, where the program can be written in any language (I have chosen C#) and must perform some sort of networked multimedia process. It can be peer to peer or client-server based.
I have chosen to make my application Peer to Peer. Clients use UDP to broadcast their connect/disconnect to other clients on the local network, and then use TCP to send and receive .WAV files between each other.
Upon a connection request, the client will accept the TCP connection and begin reading data from the sending client.
After the data has all been read, the client may then play the .WAV file.
I have currently been trying to fix a bug in my program that required a .WAV file be sent twice instead of once, for the receiver to get the file and play it.
This has caused me to run into a problem I ran into before: Wave header is corrupt.
Before, I ran into this issue because on playing of the .WAV files, I was not setting the stream position to 0. This fixed it the first time.
However, the cause is now much more interesting because I am trying to fix a different bug.
The cause of it this time is that the data in the .WAV file stream is split. At the beginning, the very first byte of data is correct (verified by using a hexeditor to look at the bytes in the .WAV file I'm trying to send/receive) and then the stream is filled with 1023 bytes of 0's. After that, the rest of the .WAV file's data is available with no splits.
(Another send/recv trial revealed that the first byte was again correct, but the next 1023 bytes were out of sync and misplaced. The next 1023 bytes were not 0x00, but instead were from another piece of the file that was misplaced.)
I have no idea what's causing this and have taken to Wireshark to try and figure out what the issue is. I took a wireshark capture on the receiving end and found that the very first packet sent has only 1 byte of data: 0x52.
The next packet had 1460 bytes. There was no split of 0x00 after those 1460 bytes in the NetworkStream.
Provided below is my program's code. It is also available on Github at https://github.com/cparks1/ECE369ProjB-MultimediaGUI
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets; // For network programming
using System.Net; // For network programming
using System.Media; // For playing .WAV files
using System.IO; // For playing .WAV files (SoundPlayer in System.Media accepts either a filepath or an IO stream.)
namespace ProjectBMultimediaGUI
{
public partial class Form1 : Form
{
private delegate void ObjectDelegate(string msg, IPEndPoint sender);
private delegate void LabelChanger(string msg);
const int PUBLISH_PORT_NUMBER = 8030; // Port number used for publish (UDP communications)
const int TCP_PORT_NUMBER = 8031; // Port number used for the rest of communications (TCP communications)
IPAddress me = GetLocalIP(); // me is the IPAddress that your machine currently owns on the local network
const string CLIENT_ANNOUNCE = "[ECE 369] Multimedia client publish"; // UDP datagram to be sent when the client is announcing itself
const string CLIENT_DISCONNECT = "[ECE 369] Multimedia client disconnect"; // UDP datagram to be sent when the client is announcing that it is disconnecting
UdpClient pub = new UdpClient(PUBLISH_PORT_NUMBER, AddressFamily.InterNetwork); // Creates a new UDP client capable of communicating on a network on port defined by const, via IPv4 addressing
IPEndPoint UDP_BROADCAST = new IPEndPoint(IPAddress.Broadcast, PUBLISH_PORT_NUMBER); // Broadcast address and port
TcpListener tlisten = new TcpListener(IPAddress.Any,TCP_PORT_NUMBER); // Sets up a listener that looks for TCP connections
TcpClient tcprecvr;
Stream wavstream = new MemoryStream(); // Initializes a memory stream that will hold .wav file data when being written to. Will be reinitialized in packet receiving functions
Timer tmr = new Timer(); // Timer used to announce client on the local network every 250 ms
SoundPlayer splayer;
bool isClosing = false; // Used to determine if program is closing
byte[] readbuf = new byte[1024];
long wavpos = 0;
public Form1()
{
InitializeComponent();
#region Timer Setup
tmr.Interval = 250;
tmr.Start();
tmr.Tick += new EventHandler(tmr_Tick);
#endregion
}
private void tmr_Tick(object sender, EventArgs e)
{
if (!isClosing)
Announce_Client_Connect(); // Announce the client is connected every 250 ms
}
private void playpauseBUT_MouseClick(object sender, MouseEventArgs e)
{
Button sbut = (sender as Button);
splayer = new SoundPlayer(wavstream);
if (sbut.ImageIndex == 0) // If the PLAY button was clicked
{ // Initiate play functions
if (wavstream.CanRead && wavstream.Length > 0)
{
splayer.Stream.Position = 0;
splayer.Play();
}
sbut.ImageIndex = 1; // Change the button to show PAUSE
}
else // If the PAUSE button was clicked
{
splayer.Stop();
sbut.ImageIndex = 0; // Change the button to show PLAY
}
}
private void Form1_Load(object sender, EventArgs e)
{
butIML.ImageSize = new Size(playpauseBUT.Size.Width-1,playpauseBUT.Size.Height-1); // This ensures the play and pause buttons are always the same size as the button they are encased in
stopBUT.Size = playpauseBUT.Size; // Ensures the stop button is the same size as the play/pause button.
stopBUT.Location = new Point(stopBUT.Location.X, playpauseBUT.Location.Y);
pub.AllowNatTraversal(false); // Disables the ability for the program to communicate with the outside world, for security purposes
try { pub.BeginReceive(new AsyncCallback(RecvPub), null); }
catch(Exception err) { MessageBox.Show("An error occurred!\n"+err.ToString()); Application.Exit(); }
tlisten.AllowNatTraversal(false);
BeginListening(); // Begins listening for attempts to connect to the client via TCP
Announce_Client_Connect();
}
private void BeginListening()
{
tlisten.Start();
tlisten.BeginAcceptTcpClient(new AsyncCallback(RecvTcp), null);
}
private void stopBUT_MouseClick(object sender, MouseEventArgs e)
{
splayer.Stop();
playpauseBUT.ImageIndex = 0; // Change the play/pause button to show PLAY
}
private void mainMS_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(new Pen(Color.Black), mainMS.Left, mainMS.Bottom-1, mainMS.Right, mainMS.Bottom-1); // Draws a border on the bottom of the main menu strip.
e.Graphics.DrawLine(new Pen(Color.Black), mainMS.Left, mainMS.Top, mainMS.Right, mainMS.Top); // Draws a border on the top of the menu strip.
}
private void RecvPub(IAsyncResult res) // Function used to handle received UDP messages
{
IPEndPoint recv = new IPEndPoint(IPAddress.Any, PUBLISH_PORT_NUMBER);
byte[] message = null;
string dmessage;
if (!isClosing)
message = pub.EndReceive(res, ref recv);
if(message != null) // If a message was received
{
ObjectDelegate del = new ObjectDelegate(HandleUDPDatagram);
dmessage = Encoding.ASCII.GetString(message);
del.Invoke(dmessage, recv);
HandleUDPDatagram(dmessage, recv);
}
if (!isClosing)
pub.BeginReceive(new AsyncCallback(RecvPub), null);
}
private void RecvTcp(IAsyncResult res)
{
LabelChanger lblchgr = new LabelChanger(dataavailable); // Used for cross thread operations on dataavailLBL
wavstream = new MemoryStream(); // Clear the wav stream, we don't want two wav files in one stream, it would cause errors.
lblchgr.Invoke("Data unavailable."); // No data available yet.
//tcprecvr = tlisten.AcceptTcpClient(); // Accept the incoming TCP connection.
tcprecvr = tlisten.EndAcceptTcpClient(res); // Create a new TCP connection with the requester
NetworkStream stream = tcprecvr.GetStream(); // Get the TCP network stream
if (stream.CanRead)
{
while (!stream.DataAvailable) ;
stream.BeginRead(readbuf, 0, readbuf.Length, new AsyncCallback(RecvTCPData), null);
}
else
{
tcprecvr.Close();
MessageBox.Show("An error has occurred. Unable to read incoming TCP stream.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
}
private void RecvTCPData(IAsyncResult res)
{
LabelChanger lblchgr = new LabelChanger(dataavailable); // Used for cross thread operations on dataavailLBL
wavpos = 0; // Reset the WAV stream position
NetworkStream stream = tcprecvr.GetStream(); // Get the TCP data stream
int nbytes = stream.EndRead(res); // Get the number of bytes read
if (nbytes == 0) // Finished reading
{
tcprecvr.Close(); // Close the TCP connection
lblchgr.Invoke("Data available!"); // Inform the user there is a .WAV file to be played
BeginListening(); // Begin listening to connection requests again
//return;
}
else // Not finished reading, data in buffer
{
wavstream.Write(readbuf, 0, readbuf.Length); // Write WAV data to wav stream
stream.BeginRead(readbuf, 0, readbuf.Length, new AsyncCallback(RecvTCPData), null); // begin read again
}
}
private void dataavailable(string msg)
{
if(InvokeRequired)
{
LabelChanger method = new LabelChanger(dataavailable);
Invoke(method, msg);
return;
}
dataavailLBL.Text = "Data available!";
}
private void HandleUDPDatagram(string msg, IPEndPoint sender) // Used for handling UDP messages
{
if (!sender.Address.Equals(me)) // Verifies the UDP datagram received isn't from your own machine.
{ //This is done because some UDP datagrams are sent to the broadcast address, which means we receive what we've sent. We obviously don't want packets from ourselves so we block them.
if (InvokeRequired && !isClosing) // Used for handling thread magic. Please don't ask me to explain this.
{
ObjectDelegate method = new ObjectDelegate(HandleUDPDatagram);
Invoke(method, msg, sender);
return;
}
switch (msg)
{
case CLIENT_ANNOUNCE: // If we've received a client connection message
if (!hostsLB.Items.Contains(sender.Address)) // If the client is not already in the list box
hostsLB.Items.Add(sender.Address); // Add the client to the listbox of clients
break;
case CLIENT_DISCONNECT: // If we've received a client disconnection message
if (hostsLB.Items.Contains(sender.Address)) // If the client is in the listbox
hostsLB.Items.Remove(sender.Address); // Remove the client from the listbox of clients
break;
}
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
isClosing = true;
Announce_Client_Disconnect(); // Declare your disconnection to the other clients on the network
}
private void Announce_Client_Disconnect()
{
byte[] dgram = Encoding.ASCII.GetBytes(CLIENT_DISCONNECT); // Encode the client disconnection message into an array of bytes
pub.Send(dgram, dgram.Length, UDP_BROADCAST); // Send the disconnection message off to all clients on the network via the broadcast address
}
private void Announce_Client_Connect()
{
byte[] dgram = Encoding.ASCII.GetBytes(CLIENT_ANNOUNCE); // Encode the client connection message into an array of bytes
pub.Send(dgram, dgram.Length, UDP_BROADCAST); // Send the connection message off to all clients on the network via the broadcast address
}
private void OpenBrowse()
{ // This function allows the user to browse for a file and then sets the file path textbox with the path of the file.
OpenFileDialog fopen = new OpenFileDialog();
fopen.CheckFileExists = true; fopen.CheckPathExists = true; fopen.Filter = "WAV Files|*.wav";
fopen.ShowDialog();
filepathTB.Text = fopen.FileName;
}
private void sendwavBUT_MouseClick(object sender, MouseEventArgs e)
{
if (hostsLB.Items.Count > 0 && hostsLB.SelectedItem != null)
{
TcpClient tcpsender = new TcpClient((hostsLB.SelectedItem as IPAddress).ToString(),TCP_PORT_NUMBER); // Connect to the client
sendwavBUT.Enabled = false; filesendPB.UseWaitCursor = true;
try
{
//byte[] buf = new byte[1024]; // !! TRIAL !!
FileStream fs = new FileStream(filepathTB.Text, FileMode.Open);
int dat = 0;
while(fs.CanRead && fs.Position!=fs.Length)
{
dat = fs.ReadByte();
if (dat != -1)
{
tcpsender.GetStream().WriteByte((byte)dat);
filesendPB.Value = (int)((fs.Position / fs.Length) * 100);
}
}
fs.Close(); // Release any resources used by the file stream.
}
catch(Exception err) { MessageBox.Show(err.ToString(),"Error",MessageBoxButtons.OK,MessageBoxIcon.Error); }
MessageBox.Show("File send complete.");
tcpsender.Close(); // Release any resources used by the TCP stream and close the TCP connection.
sendwavBUT.Enabled = true; filesendPB.UseWaitCursor = false; // Re-enable the send button.
}
else if (hostsLB.Items.Count <= 0)
MessageBox.Show("There are no clients to send this file to!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
else
MessageBox.Show("You must select a client!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
static IPAddress GetLocalIP() // Has the machine report its local network IP address
{ // This code snippet has been taken from StackOverflow and adapted to return an IPAddress rather than a string
IPHostEntry host;
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
if (ip.AddressFamily.ToString() == "InterNetwork")
return ip;
return null;
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{ Application.Exit(); }
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{ OpenBrowse(); }
private void browseBUT_MouseClick(object sender, MouseEventArgs e)
{ OpenBrowse(); }
}
}
Provided also is a picture of the GUI:
Thank you for any input you may have, this issue has been driving me nuts! :)
Just looking at the stream reads/writes, it looks like you have a bug on this line:
wavstream.Write(readbuf, 0, readbuf.Length); // Write WAV data to wav stream
It should be:
wavstream.Write(readbuf, 0, nbytes); // Write WAV data to wav stream
I am working on a transportation Project RailWay. Let me explain the project :there are a lot of sensors during the path of the train ,so when the train passes one of these sensors ,the sensor sends a value to CTC(A computer that manages the sensors) server the value is 1 or 0 ,1 means that the train arrive the sensor and 0 means the train left the sensor ,so every thing is ok ,now here is the scope of my project:
The CTC server send the value to MY-SERVER for example :ID=16(SENSOR-ID),state=0.it means that the train left the sensor that its id is 16 ,Note:That i know the location of sensors by id .so My problems start here : the CTC server sends its data by TCP ,so i have to create a listener to listen the data that comes from the CTC server ,(Note:Sometimes the data that comes from CTC is a lot and maybe some data be lost) ,I create a program using c# that listen the port but sometimes the data that coes fro CTC are lost why ?
So let me explain my programs:
It's the code that i wrote to get the data :
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 3456);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
}
tcpClient.Close();
}
}
And here i call the server class :
class Program
{
static void Main(string[] args)
{
Server obj=new Server();
}
}
The CTC code that sends data is like this(An example) :
static void Main(string[] args)
{
TcpClient client = new TcpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3456);
client.Connect(serverEndPoint);
using (NetworkStream clientStream = client.GetStream())
{
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Server!");
clientStream.Write(buffer, 0, buffer.Length);
}
}
But sometimes my programs(SERVER CODE) lost data ?!!!Why ?Any idea ?
Best regards
Here is my solution of a basic Client/Server application using StreamReader and StreamWriter
Basic structure
The server will be running a TcpListener. We will use the Pending() method to check for waiting connections while not blocking the thread from exiting. When a new connection is waiting we will accept it with the AcceptTcpClient(), create a new instance of our own Client class and add it to a List<Client()> to mange it later. The class Client will store the methods to send data and hold informations like ID etc.
Code
Server Class:
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace CTCServer
{
class Server
{
//Stores the IP Adress the server listens on
private IPAddress ip;
//Stores the port the server listens on
private int port;
//Stores the counter of connected clients. *Note* The counter only gets increased, it acts as "id"
private int clientCount = 0;
//Defines if the server is running. When chaning to false the server will stop and disconnect all clients.
private bool running = true;
//Stores all connected clients.
public List<Client> clients = new List<Client>();
//Event to pass recived data to the main class
public delegate void GotDataFromCTCHandler(object sender, string msg);
public event GotDataFromCTCHandler GotDataFromCTC;
//Constructor for Server. If autoStart is true, the server will automaticly start listening.
public Server(IPAddress ip, int port, bool autoStart = false)
{
this.ip = ip;
this.port = port;
if (autoStart)
this.Run();
}
//Starts the server.
public void Run()
{
//Run in new thread. Otherwise the whole application would be blocked
new Thread(() =>
{
//Init TcpListener
TcpListener listener = new TcpListener(this.ip, this.port);
//Start listener
listener.Start();
//While the server should run
while (running)
{
//Check if someone wants to connect
if (listener.Pending())
{
//Client connection incoming. Accept, setup data incoming event and add to client list
Client client = new Client(listener.AcceptTcpClient(), this.clientCount);
//Declare event
client.internalGotDataFromCTC += GotDataFromClient;
//Add to list
clients.Add(client);
//Increase client count
this.clientCount++;
}
else
{
//No new connections. Sleep a little to prevent CPU from going to 100%
Thread.Sleep(100);
}
}
//When we land here running were set to false or another problem occured. Stop server and disconnect all.
Stop();
}).Start(); //Start thread. Lambda \(o.o)/
}
//Fires event for the user
private void GotDataFromClient(object sender, string data)
{
//Data gets passed to parent class
GotDataFromCTC(sender, data);
}
//Send string "data" to all clients in list "clients"
public void SendToAll(string data)
{
//Call send method on every client. Lambda \(o.o)/
this.clients.ForEach(client => client.Send(data));
}
//Stop server
public void Stop()
{
//Exit listening loop
this.running = false;
//Disconnect every client in list "client". Lambda \(o.o)/
this.clients.ForEach(client => client.Close());
//Clear clients.
this.clients.Clear();
}
}
}
Client Class
using System.IO;
using System.Net.Sockets;
using System.Threading;
namespace CTCServer
{
class Client
{
//Stores the TcpClient
private TcpClient client;
//Stores the StreamWriter. Used to write to client
private StreamWriter writer;
//Stores the StreamReader. Used to recive data from client
private StreamReader reader;
//Defines if the client shuld look for incoming data
private bool listen = true;
//Stores clientID. ClientID = clientCount on connection time
public int id;
//Event to pass recived data to the server class
public delegate void internalGotDataFromCTCHandler(object sender, string msg);
public event internalGotDataFromCTCHandler internalGotDataFromCTC;
//Constructor
public Client(TcpClient client, int id)
{
//Assain members
this.client = client;
this.id = id;
//Init the StreamWriter
writer = new StreamWriter(this.client.GetStream());
reader = new StreamReader(this.client.GetStream());
new Thread(() =>
{
Listen(reader);
}).Start();
}
//Reads data from the connection and fires an event wih the recived data
public void Listen(StreamReader reader)
{
//While we should look for new data
while(listen)
{
//Read whole lines. This will read from start until \r\n" is recived!
string input = reader.ReadLine();
//If input is null the client disconnected. Tell the user about that and close connection.
if (input == null)
{
//Inform user
input = "Client with ID " + this.id + " disconnceted.";
internalGotDataFromCTC(this, input);
//Close
Close();
//Exit thread.
return;
}
internalGotDataFromCTC(this, input);
}
}
//Sends the string "data" to the client
public void Send(string data)
{
//Write and flush data
writer.WriteLine(data);
writer.Flush();
}
//Closes the connection
public void Close()
{
//Stop listening
listen = false;
//Close streamwriter FIRST
writer.Close();
//Then close connection
client.Close();
}
}
}
Test code. Note: this is a console application!
using System;
using System.Net;
namespace CTCServer
{
class Program
{
static void Main(string[] args)
{
//Set title
Console.Title = "CTC-Server";
//Create new instance of the server
Server server = new Server(IPAddress.Any, 1221);
//Handle GotDataFromCTC
server.GotDataFromCTC += GotDataFromCTC;
//Start the server. We could use the autoStart in constructor too.
server.Run();
//Inform about the running server
Console.WriteLine("Server running");
//Listen for input.
while(true)
{
//Read input line from cmd
string input = Console.ReadLine();
//Stores the command itself
string command;
//Stores parameters
string param = "";
//If input line contains a whitespace we have parameters that need to be processed.
if(input.Contains(" "))
{
//Split the command from the parameter. Parte before whitespace = command, rest = parameters
command = input.Split(' ')[0];
param = input.Substring(command.Length +1);
}
else
{
//No whitespace, so we dont have any parameters. Use whole input line as command.
command = input;
}
//Process the command
switch(command)
{
//Sends a string to all clients. Everything behind "send " (Note the whitespace) will be send to the client. Exanple "send hello!" will send "hello!" to the client.
case "send":
{
//Give some feedback
Console.WriteLine("Send to all clients: {0}", param);
//Send data
server.SendToAll(param);
//Done
break;
}
//Closes connection to all clients and exits. No parameters.
case "exit":
{
//Stop the server. This will disconncet all clients too.
server.Stop();
//Clean exit
Environment.Exit(0);
//Done. We wont get here anyway.
break;
}
}
}
}
//Recived data from clien. Show it!
static void GotDataFromCTC(object sender, string data)
{
Console.WriteLine("Data from CTC-Server with ID {0} recived:\r\n{1}", (sender as Client).id, data);
}
}
}
NOTE that this application doesnt have any exception handling. I did this to show a direction, you will need to modify the code to fit to your requirements. Let me know if you need something.
Example Project (Visual Studio 2013 Pro): Download | Virustoal
I found an article about Socket programming that using StreamReader ,It using one thread ,and no information lost is happened
You can take a look here :
http://www.codeproject.com/Articles/511814/Multi-client-per-one-server-socket-programming-in
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());
}
}
}
}