How Do I Read And Parse XML From A TCP Stream? - c#

Thanks for taking the time to look at my question! This is my first post, so please excuse me if i did something wrong forum wise :)
EDIT: I appear to have solved my problem. I simply read the TCP stream 1 line at a time, and from there I use if statements to determine the reading start and stop spots.
Updated Code:
using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
using System.Text;
namespace RFLY_CMD
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting...");
TcpListener server = new TcpListener(IPAddress.Parse("0.0.0.0"), 7362);
server.Start();
Console.WriteLine("Listening...");
Console.WriteLine();
while (true)
{
ClientWorking cw = new ClientWorking(server.AcceptTcpClient());
new Thread(new ThreadStart(cw.DoSomethingWithClient)).Start();
}
}
}
class ClientWorking
{
private Stream ClientStream;
private TcpClient Client;
public ClientWorking(TcpClient Client)
{
this.Client = Client;
ClientStream = Client.GetStream();
}
public void DoSomethingWithClient()
{
StreamWriter sw = new StreamWriter(ClientStream);
StreamReader sr = new StreamReader(sw.BaseStream);
string data;
bool cap = false;
string full_string = null;
try
{
while (true)
{
data = sr.ReadLine();
if (!string.IsNullOrEmpty(data) && !string.IsNullOrWhiteSpace(data) || cap)
{
if(data == "... start")
{
cap = true;
Console.WriteLine("---START FOUND!!!---");
}
if (cap)
{
Console.WriteLine(data);
full_string += data + "--:BREAK:--";
}
if (data == "... end")
{
cap = false;
Console.WriteLine("---END FOUND!!!---");
Console.WriteLine();
Console.WriteLine("-------------FULL STRING-------------");
Console.WriteLine(full_string);
}
}
}
}
finally
{
Console.Write("Ending...");
sw.Close();
}
}
}
}
Working Screenshot
End Edit.
Ok, so here is the problem... I have an application sending XML like so:
XML Screenshot
But, I only need the string of the text in the red box shown here:
Target Data
This is my first time dealing with XML and I have a little experience with TCP. Other than that, I am in WAY over my head.
Thanks in advance!
Here is my code:
using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
using System.Text;
using System.Xml;
namespace RFLY_CMD
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting...");
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 7362);
server.Start();
Console.WriteLine("Started.");
while (true)
{
ClientWorking cw = new ClientWorking(server.AcceptTcpClient());
new Thread(new ThreadStart(cw.DoSomethingWithClient)).Start();
}
}
}
class ClientWorking
{
private Stream ClientStream;
private TcpClient Client;
public ClientWorking(TcpClient Client)
{
this.Client = Client;
ClientStream = Client.GetStream();
}
public void DoSomethingWithClient()
{
StreamWriter sw = new StreamWriter(ClientStream);
StreamReader sr = new StreamReader(sw.BaseStream);
string data;
try
{
while (true)
{
data = sr.ReadToEnd();
if (!string.IsNullOrEmpty(data) && !string.IsNullOrWhiteSpace(data))
{
//Console.Clear();
Console.WriteLine(data);
//Console.WriteLine("---------------");
}
sr.DiscardBufferedData();
}
}
finally
{
Console.Write("Ending...");
sw.Close();
}
}
}
}

Related

c# windows forms app /client server /checking client input to do something is not working in

I'm creating a client server app using c# and what it does :
1- the client sends a msg then the server sends it back to the client
2- I want to check what the client send and do some process like if the client send "chrome"
the server checks it and open chrome.exe
I don't know why its not working here on my code:
when the client sends chrome it always shows client disconnected message
also i cant convert it to windows froms app its shows lots of errors
#server code!
using System;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;
using System.Text;
namespace consoleTcpServer {
class Program {
class ConnectionHandler {
private Socket client;
private NetworkStream ns;
private StreamReader reader;
private StreamWriter writer;
private static int connections = 0;
//The constructor take the accepted client as argument
public ConnectionHandler(Socket client) {
this.client = client;
}
public void HandleConnection() {
try {
ns = new NetworkStream(client);
reader = new StreamReader(ns);
writer = new StreamWriter(ns);
connections++;
Console.WriteLine("New client accepted: {0} active connections",
connections);
writer.WriteLine("Welcome to my server");
writer.Flush();
string input;
while ((input = reader.ReadLine()).Length != 0) {
if (input.Contains("chrome")) {
System.Diagnostics.Process.Start("chrome.exe", "www.google.com");
} else if (input.Contains("fox")) {
System.Diagnostics.Process.Start("firefox.exe", "www.facebook.com");
}
Console.WriteLine(input);
writer.WriteLine(input);
writer.Flush();
}
// ns.Close();
// client.Close();
connections--;
Console.WriteLine("Client disconnected: {0} active connections", connections);
} catch (Exception) {
connections--;
Console.WriteLine("Client disconnected: {0} active connections",
connections);
}
}
}
static void Main(string[] args) {
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 9050);
server.Bind(localEP);
server.Listen(10);
Console.WriteLine("Waiting for a client");
while (true) {
try {
Socket client = server.Accept();
ConnectionHandler handler = new ConnectionHandler(client);
Thread thread = new Thread(new ThreadStart(handler.HandleConnection));
thread.Start();
} catch (Exception) {
Console.WriteLine("Connection failed ..");
}
//client.Close();
//server.Shutdown();
}
}
}
}
#client code
using System;
using System.Net;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Text;
namespace consoleTcpClient {
class Program {
static void Main(string[] args) {
// Console.WriteLine("Hello World!");
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
client.Connect(remoteEP);
NetworkStream stream = new NetworkStream(client);
StreamReader reader = new StreamReader(stream);
StreamWriter writer = new StreamWriter(stream);
String input = reader.ReadLine();
Console.WriteLine(input);
String line = null;
while (true) {
Console.Write("Enter Message for Server <Enter to Stop >: ");
line = Console.ReadLine();
//writing for server
writer.WriteLine(line);
writer.Flush();
if (line.Length != 0) {
line = "Echo: " + reader.ReadLine();
Console.WriteLine(line);
}
}
// client.Close();
}
}
}

How to get TCP connection ids of all connected clients in c# console application

How can i get TCP Connection ID of all the connected clients.Actually i am making a program in c# (console application) that will return array with Connection Ids and IMEIs of connected clients. below code is simple client and server program so how can i get Connection id ?
Client Program :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Sockets;
namespace TcpEchoClient
{
class TcpEchoClient
{
static void Main(string[] args)
{
Console.Title = "TCP Client";
String server = "xxx.xxx.x.xx"; // IP address
byte[] byteBuffer = Encoding.ASCII.GetBytes("Test Message");
int servPort = 1;
TcpClient client = null;
NetworkStream netStream = null;
try
{
client = new TcpClient(server, servPort);
Console.WriteLine("Connected to server... sending echo string");
netStream = client.GetStream();
netStream.Write(byteBuffer, 0, byteBuffer.Length);
Console.WriteLine("Sent {0} bytes to server...", byteBuffer.Length);
int totalBytesRcvd = 0;
int bytesRcvd = 0;
while (totalBytesRcvd < byteBuffer.Length)
{
if ((bytesRcvd = netStream.Read(byteBuffer, totalBytesRcvd, byteBuffer.Length - totalBytesRcvd)) == 0)
{
Console.WriteLine("Connection closed prematurely.");
break;
}
totalBytesRcvd += bytesRcvd;
}
Console.WriteLine("Received {0} bytes from server: {1}", totalBytesRcvd, Encoding.ASCII.GetString(byteBuffer, 0, totalBytesRcvd));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
netStream.Close();
client.Close();
}
}
}
}
Server Program :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
sing System.Net;
using System.Net.Sockets;
namespace TcpEchoServer
{
class TcpEchoServer
{
private const int BUFSIZE = 32;
static void Main(string[] args)
{
Console.Title = "TCP Server";
int servPort = 1;
TcpListener listener = null;
try
{
listener = new TcpListener(IPAddress.Any,servPort);
listener.Start();
}
catch(SocketException se)
{
Console.WriteLine(se.ErrorCode + ": " + se.Message);
Environment.Exit(se.ErrorCode);
}
byte[] rcvBuffer = new byte[BUFSIZE];
int bytesRcvd;
for (; ; )
{
TcpClient client = null;
NetworkStream netStream = null;
try
{
client = listener.AcceptTcpClient();
netStream = client.GetStream();
Console.Write("Handling client - ");
int totalBytesEchoed = 0;
while ((bytesRcvd = netStream.Read(rcvBuffer,0,rcvBuffer.Length)) >0)
{
netStream.Write(rcvBuffer,0,bytesRcvd);
totalBytesEchoed += bytesRcvd;
}
Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);
netStream.Close();
client.Close();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
netStream.Close();
}
}
}
}
}
Can anyone point me in the right direction?
Thanks in advance.

How to send messages to all clients in multithread chat server?

Sorry for asking about the 'same' thing over and over again. It's yet another edition of the chat. With a lot of searching around I've finally found out how to pass the client list (or at least I hope so) to the Chat function.
However I don't know if this is even supposed to work:
Everytime a client connects :
clients.Add(clientSocket);
var ctThread = new System.Threading.Thread(() => Chat(clients));
where the Chat function hopefully correctly receives the clients via
public void Chat(List<TcpClient> clients)
and then writes this out
foreach (var client in clients)
{
writer.Write(message);
}
With the client having 2 threads (not sure if they can actually read/write at the same time)
Thread ctThread = new Thread(Write);
Thread ctThread2 = new Thread(Read);
ctThread2.Start();
ctThread.Start();
Did I pass the client list to the function properly? and can it actually correctly send the messages? Because right now the server is not responding to anything that I type on the client.
Full code:
Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.IO;
namespace MultiServeris
{
class Multiserveris
{
static void Main(string[] args)
{
TcpListener ServerSocket = new TcpListener(1000);
ServerSocket.Start();
List<TcpClient> clients = new List<TcpClient>();
Console.WriteLine("Server started.");
while (true)
{
TcpClient clientSocket = ServerSocket.AcceptTcpClient();
handleClient client = new handleClient();
clients.Add(clientSocket);
client.startClient(clientSocket,clients);
}
}
}
public class handleClient
{
TcpClient clientSocket;
public void startClient(TcpClient inClientSocket, List<TcpClient> clients)
{
this.clientSocket = inClientSocket;
var ctThread = new System.Threading.Thread(() => Chat(clients));
}
public void Chat(List<TcpClient> clients)
{
BinaryReader reader = new BinaryReader(clientSocket.GetStream());
BinaryWriter writer = new BinaryWriter(clientSocket.GetStream());
while (true)
{
string message = reader.ReadString();
foreach (var client in clients)
{
writer.Write(message);
}
}
}
}
}
Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace Klientas
{
class Klientas
{
public static void Write()
{
while (true)
{
TcpClient clientSocket = new TcpClient("localhost", 1000);
string str = Console.ReadLine();
BinaryWriter writer = new BinaryWriter(clientSocket.GetStream());
writer.Write(str);
}
}
public static void Read()
{
while (true)
{
TcpClient clientSocket = new TcpClient("localhost", 1000);
BinaryReader reader = new BinaryReader(clientSocket.GetStream());
string message = reader.ReadString();
Console.WriteLine(message);
}
}
static void Main(string[] args){
Thread ctThread = new Thread(Write);
Thread ctThread2 = new Thread(Read);
ctThread2.Start();
ctThread.Start();
}
}
}
TCP is not design for broadcasting which is why you're having to loop through all your clients. A better approach would be to use a protocol that supports brodcast use the SignalR Framework or if you want baremetal access use UDP. Here's a great SignalR chat example.
https://dhavalupadhyaya.wordpress.com/tag/signalr-chat-example/

Example of Named Pipes

How do I write a simple--bare minimum needed for it to work--test application that illustrates how to use IPC/Named Pipes?
For example, how would one write a console application where Program 1 says "Hello World" to Program 2 and Program 2 receives message and replies "Roger That" to Program 1.
using System;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
StartServer();
Task.Delay(1000).Wait();
//Client
var client = new NamedPipeClientStream("PipesOfPiece");
client.Connect();
StreamReader reader = new StreamReader(client);
StreamWriter writer = new StreamWriter(client);
while (true)
{
string input = Console.ReadLine();
if (String.IsNullOrEmpty(input)) break;
writer.WriteLine(input);
writer.Flush();
Console.WriteLine(reader.ReadLine());
}
}
static void StartServer()
{
Task.Factory.StartNew(() =>
{
var server = new NamedPipeServerStream("PipesOfPiece");
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
StreamWriter writer = new StreamWriter(server);
while (true)
{
var line = reader.ReadLine();
writer.WriteLine(String.Join("", line.Reverse()));
writer.Flush();
}
});
}
}
}
For someone who is new to IPC and Named Pipes, I found the following NuGet package to be a great help.
GitHub: Named Pipe Wrapper for .NET 4.0
To use first install the package:
PS> Install-Package NamedPipeWrapper
Then an example server (copied from the link):
var server = new NamedPipeServer<SomeClass>("MyServerPipe");
server.ClientConnected += delegate(NamedPipeConnection<SomeClass> conn)
{
Console.WriteLine("Client {0} is now connected!", conn.Id);
conn.PushMessage(new SomeClass { Text: "Welcome!" });
};
server.ClientMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message)
{
Console.WriteLine("Client {0} says: {1}", conn.Id, message.Text);
};
server.Start();
Example client:
var client = new NamedPipeClient<SomeClass>("MyServerPipe");
client.ServerMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message)
{
Console.WriteLine("Server says: {0}", message.Text);
};
client.Start();
Best thing about it for me is that unlike the accepted answer here it supports multiple clients talking to a single server.
You can actually write to a named pipe using its name, btw.
Open a command shell as Administrator to get around the default "Access is denied" error:
echo Hello > \\.\pipe\PipeName
Linux dotnet core doesn't support namedpipes!
Try TcpListener if you deploy to Linux
This NamedPipe Client/Server code round trips a byte to a server.
Client writes byte
Server reads byte
Server writes byte
Client reads byte
DotNet Core 2.0 Server ConsoleApp
using System;
using System.IO.Pipes;
using System.Threading.Tasks;
namespace Server
{
class Program
{
static void Main(string[] args)
{
var server = new NamedPipeServerStream("A", PipeDirection.InOut);
server.WaitForConnection();
for (int i =0; i < 10000; i++)
{
var b = new byte[1];
server.Read(b, 0, 1);
Console.WriteLine("Read Byte:" + b[0]);
server.Write(b, 0, 1);
}
}
}
}
DotNet Core 2.0 Client ConsoleApp
using System;
using System.IO.Pipes;
using System.Threading.Tasks;
namespace Client
{
class Program
{
public static int threadcounter = 1;
public static NamedPipeClientStream client;
static void Main(string[] args)
{
client = new NamedPipeClientStream(".", "A", PipeDirection.InOut, PipeOptions.Asynchronous);
client.Connect();
var t1 = new System.Threading.Thread(StartSend);
var t2 = new System.Threading.Thread(StartSend);
t1.Start();
t2.Start();
}
public static void StartSend()
{
int thisThread = threadcounter;
threadcounter++;
StartReadingAsync(client);
for (int i = 0; i < 10000; i++)
{
var buf = new byte[1];
buf[0] = (byte)i;
client.WriteAsync(buf, 0, 1);
Console.WriteLine($#"Thread{thisThread} Wrote: {buf[0]}");
}
}
public static async Task StartReadingAsync(NamedPipeClientStream pipe)
{
var bufferLength = 1;
byte[] pBuffer = new byte[bufferLength];
await pipe.ReadAsync(pBuffer, 0, bufferLength).ContinueWith(async c =>
{
Console.WriteLine($#"read data {pBuffer[0]}");
await StartReadingAsync(pipe); // read the next data <--
});
}
}
}

C# Connecting two tcp sockets together

I'm not sure if the title is all that informative.
I am trying to find/write a socket server that will accept a connection from the client (telnet) and then on behalf of the connected client, connect to one of four telnet servers inside the network.
Once connected I keep a counter of how many connections there are, and then if there are 4 total connections, disallow any new connections until one of the four is available.
I have written this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static int nodeCount = 4;
static int currentNode = 1;
static void Main(string[] args)
{
ServerProgram server = new ServerProgram();
}
class ServerProgram
{
private TcpListener tcpPrimaryListener;
private Thread listenThread;
public ServerProgram()
{
this.tcpPrimaryListener = new TcpListener(IPAddress.Any, 23);
Console.WriteLine("Telnet BBS Port Concentrator Server Started.");
Console.WriteLine("--------------------------------------------");
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpPrimaryListener.Start();
while (true)
{
TcpClient client = this.tcpPrimaryListener.AcceptTcpClient();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
if (currentNode <= nodeCount)
{
Console.WriteLine("Connection thread created.");
StreamWriter swStream;
StreamWriter swStream2;
StreamReader srStream;
StreamReader srStream2;
TcpClient tcpClient = (TcpClient)client;
NetworkStream tcpClientStream = tcpClient.GetStream();
TcpClient telnet = new TcpClient("192.168.100.5" + currentNode, 23);
NetworkStream telnetStream = telnet.GetStream();
currentNode++;
while (true)
{
srStream = new StreamReader(tcpClient.GetStream());
swStream2 = new StreamWriter(tcpClient.GetStream());
srStream2 = new StreamReader(telnet.GetStream());
swStream = new StreamWriter(telnet.GetStream());
swStream.Write(srStream.ReadToEnd());
swStream2.Write(srStream2.ReadToEnd());
}
}
}
}
}
}
I've changed this example multiple times, so I don't really know anymore what I have and have not tried. I'm willing to try anything.
The purpose is actually running this to allow one telnet port open through the firewall, and allowing connections into a small network of DOS machines running telnet fossil driver BBS software. I would just like to redirect telnet traffic to an available system using only one port.
The problem is that I cannot figure out how to actually connect the two sockets together and pass data between them as it happens. The incoming socket and the socket I created on behalf of the server to the server.
Thanks.
UPDATE:
This is what is working for me, I'm still looking over for bugs but it's working so far.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static int nodeCount = 2;
static int currentNode = 1;
static void Main(string[] args)
{
ServerProgram server = new ServerProgram();
}
class ServerProgram
{
private TcpListener tcpPrimaryListener;
private Thread listenThread;
public ServerProgram()
{
this.tcpPrimaryListener = new TcpListener(IPAddress.Any, 23);
Console.WriteLine("Telnet BBS Port Concentrator Server Started.");
Console.WriteLine("--------------------------------------------");
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpPrimaryListener.Start();
while (true)
{
TcpClient client = this.tcpPrimaryListener.AcceptTcpClient();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
string noNodes = "Sorry all nodes are occupied.";
if (currentNode <= nodeCount)
{
Console.WriteLine("Client connected.");
TcpClient tcpClient = (TcpClient)client;
NetworkStream tcpClientStream = tcpClient.GetStream();
TcpClient telnet = new TcpClient("10.24.9.11", 23);
//TcpClient telnet = new TcpClient("192.168.100.5" + currentNode, 23);
NetworkStream telnetStream = telnet.GetStream();
currentNode++;
ByPass linkedSockets = new ByPass(tcpClientStream, telnetStream);
}
else
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream tcpClientStream = tcpClient.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
tcpClientStream.Write(Encoding.ASCII.GetBytes(noNodes), 0, noNodes.Length);
}
}
}
public class ByPass
{
public ByPass(Stream s1, Stream s2)
{
var cTokenSource = new CancellationTokenSource();
var cToken = cTokenSource.Token;
Task.Factory.StartNew(() => Process(s1, s2, cToken, cTokenSource), cToken);
Task.Factory.StartNew(() => Process(s2, s1, cToken, cTokenSource), cToken);
cToken.Register(() => cancelNotification());
}
public void Process(Stream s1, Stream s2, CancellationToken ct, CancellationTokenSource cTokenSource)
{
byte[] buf = new byte[0x10000];
while (true)
{
if (ct.IsCancellationRequested)
{
break;
}
try
{
int len = s1.Read(buf, 0, buf.Length);
s2.Write(buf, 0, len);
}
catch
{
s1.Close(); s2.Close();
cTokenSource.Cancel();
break;
}
}
}
}
static void cancelNotification()
{
Console.WriteLine("Client disconnected.");
currentNode--;
}
}
}
I think, you can create a class similar to below to pass data between two streams
public class ByPass
{
public ByPass(Stream s1, Stream s2)
{
Task.Factory.StartNew(() => Process(s1, s2));
Task.Factory.StartNew(() => Process(s2, s1));
}
public void Process(Stream sIn, Stream sOut)
{
byte[] buf = new byte[0x10000];
while (true)
{
int len = sIn.Read(buf, 0, buf.Length);
sOut.Write(buf, 0, len);
}
}
}
I have made little changes and it works perfect on my side
public class StreamTransmitter
{
static TaskCompletionSource<bool> ts;
public static async Task Start(Stream s1, Stream s2, CancellationToken token)
{
ts = new TaskCompletionSource<bool>();
Process(s1, s2, token);
Process(s2, s1, token);
await ts.Task;
}
private static async Task Process(Stream sIn, Stream sOut, CancellationToken token)
{
byte[] buf = new byte[0x10000];
int len = 0;
do
{
len = await sIn.ReadAsync(buf, 0, buf.Length, token);
await sOut.WriteAsync(buf, 0, len, token);
}
while (len > 0 && !token.IsCancellationRequested);
ts.SetResult(true);
}
}

Categories

Resources