WiFi communication between C# and ESP8266 [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm working on school project right now and I'm looking for the simplest way to connect C# with ESP8266 not via SerialPort (COM4) but via WiFi module on ESP8266 (I have to use this method). I have to build simple project to sending measured data from ESP to C# and also receiving my own defined control commands (strings like "LEDON" "LEDOFF" etc.) from C# to ESP just like remote control of measurement project. I have low knowledge in C# same as basics of servers/internet and things like that. I have everything done in Arduino IDE code but I'm stuck on C# cause I never before programmed there. I hope you understand my bad English and concept of my question. :)
EDIT:
Well, so I did some changes in my school project and now I am on this stage, where I need to solve this part of code. I hope that is last step to finish my project. All I have to do is solve Writing data from C# to ESP using unfilled method named "Writing" in following code:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace ESP8266
{
public class Projekt
{
public event MessageEventHandler Message;
public delegate void MessageEventHandler(Projekt sender, string Data);
public TcpListener server;
public Thread W_Thread;
public Thread R_Thread;
public bool IsLiserning = true;
public TcpClient client;
public StreamReader clientdata;
public StreamWriter serverdata;
public Projekt()
{
server = new TcpListener(IPAddress.Parse(Dns.GetHostEntry(Dns.GetHostName().ToString()).AddressList[1].ToString()), 5000);
server.Start();
W_Thread = new Thread(new ThreadStart(Writing));
W_Thread.Start();
R_Thread = new Thread(new ThreadStart(Reading));
R_Thread.Start();
}
public void Reading()
{
while (IsLiserning == true)
{
if (server.Pending() == true)
{
client = server.AcceptTcpClient();
clientdata = new StreamReader(client.GetStream());
}
try
{
Message?.Invoke(this, clientdata.ReadLine());
}
catch (Exception){}
}
}
public void Writing()
{
while (IsLiserning == true)
{
if (server.Pending() == true)
{
client = server.AcceptTcpClient();
serverdata = new StreamWriter(client.GetStream());
}
try
{
//NEED_TO_SOLVE_THIS_PART
}
catch (Exception){}
}
}
}
}
Maybe there is missing something more than that part of code and you guys are able to help me I hope :) Thanks for all answers by the way :)

You may look at this project, basically you want to communicate via TCP/IP between the arduino and the C#. consider the C# as the server and the arduino as the client. Then they just need to send message to each other to communicate.
The link I'm providing is doing a lot more than needed, so if you're lost, maybe start with something really basic and look here and check the links at the end talking about c# server. They will be easier to understand compared to my first link.
[EDIT] Ok, only links answer is dangerous and not the best, so here is a really light version of what I gave through the first link:
Your server will have a list of receivers, each receiver only handle one client. It's a big simplification of one of my project, I hope that by removing lots of things I didn't break anything:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Windows.Data;
namespace DemoServer.Models
{
public class Server
{
public TcpListener Listener { get; set; }
public int Port { get; set; }
public bool IsStarted { get; private set; }
public List<Receiver> Receivers = new List<Receiver>();
public Server(int port)
{
Receivers.Clear();
BindingOperations.EnableCollectionSynchronization(Receivers, Receivers);
Port = port;
IsStarted = false;
}
public void Start()
{
if (!IsStarted)
{
try
{
Listener = new TcpListener(System.Net.IPAddress.Any, 0);
Listener.Start();
IsStarted = true;
IPAddress address = ((IPEndPoint)Listener.LocalEndpoint).Address;
int port = ((IPEndPoint) Listener.LocalEndpoint).Port;
Console.WriteLine("Server Started");
//Start Async pattern for accepting new connections
WaitForConnection();
}
catch (Exception e)
{
Console.WriteLine(e);
IsStarted = false;
}
}
}
public void Stop()
{
if (IsStarted)
{
Listener.Stop();
IsStarted = false;
Receivers.Clear();
Console.WriteLine("Server Stopped");
}
}
private void WaitForConnection()
{
Listener.BeginAcceptTcpClient(new AsyncCallback(ConnectionHandler), null);
}
private void ConnectionHandler(IAsyncResult ar)
{
if (IsStarted)
{
Receiver newClient = new Receiver(Listener.EndAcceptTcpClient(ar), this);
newClient.Start();
Receivers.Add(newClient);
WaitForConnection();
}
}
public void SomeInteractionBetweenClients()
{
Console.WriteLine("Interaction!");
}
}
}
Then comes the Receiver code, where you really handle the communication with your client:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Threading;
namespace DemoServer.Models
{
public class Receiver : ModelBase
{
bool ConnectionStatus = false;
private uint m_Id = 0;
public uint Id
{
get { return m_Id; }
set => SetAndRaisePropertyChanged(ref m_Id, value);
}
private Thread receivingThread;
private Thread sendingThread;
public Server Server { get; set; }
public TcpClient Client { get; set; }
public List<String> MessageQueue { get; private set; }
public Receiver(TcpClient client, Server server)
{
MessageQueue = new List<String>();
Server = server;
Client = client;
Client.ReceiveBufferSize = 1024;
Client.SendBufferSize = 1024;
ConnectionStatus = true;
}
public void Start()
{
receivingThread = new Thread(ReceivingMethod);
receivingThread.IsBackground = true;
receivingThread.Start();
sendingThread = new Thread(SendingMethod);
sendingThread.IsBackground = true;
sendingThread.Start();
}
private void Disconnect()
{
if (!ConnectionStatus) return;
ConnectionStatus = false;
Client.Client.Disconnect(false);
Client.Close();
}
private void SendingMethod()
{
while (ConnectionStatus)
{
if (MessageQueue.Count > 0)
{
var message = MessageQueue[0];
try
{
NetworkStream clientStream = Client.GetStream();
StreamWriter streamWriter = new StreamWriter(clientStream);
streamWriter.Write(message);
streamWriter.Flush();
Console.WriteLine($"We are sending '{message}' to the client");
}
catch
{
Disconnect();
}
finally
{
MessageQueue.RemoveAt(0);
}
}
Thread.Sleep(30);
}
}
private void ReceivingMethod()
{
while (ConnectionStatus)
{
if (Client.Available > 0)
{
try
{
NetworkStream clientStream = Client.GetStream();
StreamReader streamReader = new StreamReader(clientStream);
char[] puchBuffer = new char[Client.Available];
int iQtt = streamReader.Read(puchBuffer, 0, Client.Available);
string msg = String.Empty;
for (int i = 0; i < puchBuffer.Length; i++)
{
msg = $"{msg}{Convert.ToString(puchBuffer[i])}";
}
OnMessageReceived(msg);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Thread.Sleep(30);
}
}
private void OnMessageReceived(String msg)
{
// Here you can parse the messages coming ffrom the client and do whatever is needed
// If needed, you can even call some public methods from the server to forward some info to an other client for example or just the server:
// eg: Server.SomeInteractionBetweenClients();
}
}
}
I hope this will help for the communication part. For the GUI there are lots of tutorials on the web but if possible I still think WPF/MVVM is better to learn than winforms.

From my understanding your project requires 2 way communication. Making c# as server will not be ideal since there is no easy way to send command from C# to esp8266. I assume your project is utilizing esp8266 as the arduino platform (not attaching esp8266 to arduino as wifi module), please check out MQTT which is a broker for publishing and subscribing messages. That way both esp8266 and C# code and communicate via MQTT and achieve 2 way communication purpose.
for esp8266, you can check out arduino MQTT library for esp8266 here: https://github.com/knolleary/pubsubclient.

Related

TCP / Server I can from another class call the components of Form1

I have this example as a server.
The question that only works well for me on console.
I want to pass it to windows Form. And I don't know how to apply it.
Because I understand that it is bad practice from another class such as creating a Form1 Method and using a Form1 object in the Server class.
As if in the Server class I call the textbox or things like that.
The question that I think I would have to adapt all the code back for windows Form?
Or stop using the classes and use the typical TcpClient, TpcListener as in the videos that declare it at the moment in Form1.
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Chatroom
{
delegate void MessageEventHandler(object sender, MessageEventArgs e);
class MessageEventArgs : EventArgs
{
public string Message { get; private set; }
public MessageEventArgs(string message)
{
this.Message = message;
}
}
class Server
{
private TcpListener serverSocket;
private List<Worker> workers = new List<Worker>();
public Server(int port)
{
//serverSocket = new TcpListener(port);// deprecated
// the same way
serverSocket = new TcpListener(IPAddress.Any, port);
serverSocket.Start();
}
private void WaitForConnection()
{
while (true)
{
TcpClient socket = serverSocket.AcceptTcpClient();
Worker worker = new Worker(socket);
AddWorker(worker);
worker.Start();
}
}
private void Worker_MessageReceived(object sender, MessageEventArgs e)
{
BroadcastMessage(sender as Worker, e.Message);
}
private void Worker_Disconnected(object sender, EventArgs e)
{
RemoveWorker(sender as Worker);
}
private void AddWorker(Worker worker)
{
lock (this)
{
workers.Add(worker);
worker.Disconnected += Worker_Disconnected;
worker.MessageReceived += Worker_MessageReceived;
}
}
private void RemoveWorker(Worker worker)
{
lock (this)
{
worker.Disconnected -= Worker_Disconnected;
worker.MessageReceived -= Worker_MessageReceived;
workers.Remove(worker);
worker.Close();
}
}
private void BroadcastMessage(Worker from, String message)
{
lock (this)
{
message = string.Format("{0}: {1}", from.Username, message);
for (int i = 0; i < workers.Count; i++)
{
Worker worker = workers[i];
if (!worker.Equals(from))
{
try
{
worker.Send(message);
}
catch (Exception)
{
workers.RemoveAt(i--);
worker.Close();
}
}
}
}
}
class Worker
{
public event MessageEventHandler MessageReceived;
public event EventHandler Disconnected;
private readonly TcpClient socket;
private readonly Stream stream;
public string Username { get; private set; } = null;
public Worker(TcpClient socket)
{
this.socket = socket;
this.stream = socket.GetStream();
}
public void Send(string message)
{
byte[] buffer = Encoding.UTF8.GetBytes(message);
stream.Write(buffer, 0, buffer.Length);
}
public void Start()
{
new Thread(Run).Start();
}
private void Run()
{
byte[] buffer = new byte[2018];
try
{
while (true)
{
int receivedBytes = stream.Read(buffer, 0, buffer.Length);
if (receivedBytes < 1)
break;
string message = Encoding.UTF8.GetString(buffer, 0, receivedBytes);
if (Username == null)
Username = message;
else
MessageReceived?.Invoke(this, new MessageEventArgs(message));
}
}
catch (IOException) { }
catch (ObjectDisposedException) { }
Disconnected?.Invoke(this, EventArgs.Empty);
}
public void Close()
{
socket.Close();
}
}
static void Main(string[] args)
{
try
{
Server server = new Server(3393);
server.WaitForConnection();
}
catch (IOException) { }
}
}
}
The problem is this. If I have Form1.
As I relate it, as I do eg. Every time a new Client is created it is added by a ListBox from the Server class. In theory you can't or if you can or is it bad practice?
Class Server{
private void RemoveWorker(Worker worker)
{
lock (this)
{
**textbox.text +="Cliente desconectado";**
worker.Disconnected -= Worker_Disconnected;
worker.MessageReceived -= Worker_MessageReceived;
workers.Remove(worker);
worker.Close();
}
}
}
How could it be done without being in the main WinForm class?
Here are steps to help you start.
Create a new WinForms project in VisualStudio.
You project should build and show the form right away without you having to do anything.
You should have Program.cs that contains the Main() method. You do not need to change it. This is what causes the Form1 to load and display.
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
You can right-click on the Form1.cs and select View Code to see the code behind page.
There you will have the constructor that has InitializeComponent() method that creates all of your GUI "stuff".
Add a listener to run when the Form loads. This is where you can add your server stuff.
Open your GUI designer, go to Form1->Properties and add a new function to the Load
This is where you will write your code. For example, you can create and start the server.
private void Form1_Load(object sender, EventArgs e)
{
try
{
Server server = new Server(3393);
server.WaitForConnection();
}
catch (IOException) { // Put something here like a log }
}
Your server can go to a new Class that can be in a new file like Server.cs. Just make sure that WaitForConnection() is public.
This should get you started. When you run into an issue, just create a new question on SO and make sure to add your latest code.
Some suggestions:
Use a delegate to communicate between Server and the GUI
You may want to run the Server in another thread. Test it first to get it working and see if this is what you need/want
You don't normally want to run a server as WinForms project. If you accidently close the form, you kill your server.
Make sure to have a Form1_Close event and shut down your server there correctly

Multithreaded network application issues

I've looked at least a hundred threads and none gave me a solution to my specific problem so far and i got tired of looking,
I'm trying to emulate a runescape game server in C#,
I need to receive lots of connections and parse the requests and send out responses for them until the game has loaded all the files, and then proceed to the actual login protocol. this needs to be able to handle multiple connections per second, as in, i handle 3 basic protocols "jaggrab", "ondemand" and then regular game protocol i.e; login, player updating etc these are all handled on the same port
My Server class listens for connections on one thread, while on another thread my PipelineFactory handles the connections in a Queue one by one as fast as it can, meanwhile there is a TaskPool thread which is executing PoolableTask objects at their own individual intervals... this works fine except as soon as I accept a connection both the pool and server threads begin to block and furthermore, the server object stops listening for connections all together but the thread seems to keep running.. I assume this is because the TcpListener.Pending() is not being updated? but i cant seem to find a function to update this list in the docs or anywhere
I seem to be using the threads the way all the multithreading tutorials explain them to work? i dont really understand what im doing wrong.. heres the important parts of my code:
MainEntry.cs:
using System;
using System.Threading;
using gameserver.evt;
using gameserver.io;
using gameserver;
using gameserver.io.player;
public static class MainEntry
{
public static void Main(string[] args)
{
Console.WriteLine("Starting game server...");
new Thread(new ThreadStart(Server.Run)).Start();
new Thread(new ThreadStart(TaskPool.Run)).Start();
new Thread(new ThreadStart(PipelineFactory.Run)).Start();
//TODO maybe pool these
}
}
Server.cs:
using gameserver.io.player;
using gameserver.io.sql;
using gameserver.model;
using gameserver.model.player;
using util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using gameserver.io.player.pipeline;
using gameserver.evt;
using util.cache;
namespace gameserver.io
{
public class Server
{
public static TcpListener serverSocket;
public static Dictionary<int, Player> players = new Dictionary<int, Player>(Constants.MaxPlayers);
public static Database database;
public const int ListenPort = 43594;
public static bool running = true;
public static readonly Cache cache = new Cache(Constants.CacheDir);
public static void Bind()
{
serverSocket = new TcpListener(IPAddress.Parse("0.0.0.0"), ListenPort);
serverSocket.Start();
Console.WriteLine("Server started at 0.0.0.0:" + ListenPort);
}
public static void Run()
{
if (serverSocket == null)
Bind();
while(IsRunning())
{
Console.Write("serve");
var incoming = serverSocket.AcceptTcpClient();
if (incoming != null)
{
PipelineFactory.queue.Enqueue(new PlayerSocket(incoming));
}
Thread.Sleep(25);
}
}
private static void Destroy()
{
serverSocket.Stop();
//saveall players
//Environment.Exit(0);
}
public static bool Online(Player player)
{
if(player == null)
{
return false;
}
for (int i = 0; i < players.Count; i++)
{
if (player.username == players[i].username)
{
return true;
}
}
return false;
}
public static Database Database => database ?? (database = new Database());
public static bool IsRunning() => running;
}
}
TickPool.cs:
using gameserver.io;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace gameserver.evt
{
public class TaskPool
{
public static bool running = true;
public static List<PoolableTask> tasks = new List<PoolableTask>();
public static void Run()
{
do
{
long cur = Environment.TickCount;
Console.Write("tick");
foreach (PoolableTask t in tasks)
{
if (cur - t.last >= t.interval)
{
if (t == null)
continue;
t.Execute();
t.last = cur;
}
}
Thread.Sleep(100);
} while (Server.IsRunning());
}
public static void Add(PoolableTask task)
{
if(!tasks.Contains(task))
tasks.Add(task);
}
public static void Stop(PoolableTask task)
{
if(tasks.Contains(task))
tasks.Remove(task);
}
}
}
PipelineFactory.cs:
using gameserver.evt;
using gameserver.io.player.pipeline;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace gameserver.io.player
{
// simple but effective state machine for all non player model related protocol
public class PipelineFactory
{
public static Queue<PlayerSocket> queue = new Queue<PlayerSocket>(100);
private static readonly LoginPipe loginPipe = new LoginPipe();
private static readonly JaggrabPipe jgpipe = new JaggrabPipe();
private static readonly HandshakePipe handshake = new HandshakePipe();
private static readonly OnDemandPipe ondemand = new OnDemandPipe();
public static void Run()
{
while (Server.IsRunning())
{
Console.Write("pipe");
if (queue.Count() > 0)
{
var socket = queue.First();
if (socket == null || !socket.GetSocket().Connected
|| socket.state == PipeState.Play)
{
queue.Dequeue();
return;
}
switch (socket.state)
{
case PipeState.Handshake:
socket.currentPipeline = handshake;
break;
case PipeState.Jaggrab:
socket.currentPipeline = jgpipe;
break;
case PipeState.OnDemand:
socket.currentPipeline = ondemand;
break;
case PipeState.LoginResponse:
case PipeState.Block:
case PipeState.Finalize:
socket.currentPipeline = loginPipe;
break;
case PipeState.Disconnect:
//TODO: Database.saveForPlayer
socket.Close();
break;
}
try
{
if (socket.currentPipeline != null)
socket.state = socket.currentPipeline.HandleSocket(socket);
}
catch (Exception)
{
socket.Close();
queue.Dequeue();
}
}
Thread.Sleep(20);
}
}
}
}
The protocol itself really shouldn't matter just know it's all being handled asynchronously
I'm a java programmer at heart but trying to delve into C# head first so thats why my conventions might not be perfect, and I don't really know how to/dont understand intellisense documentation but at some point ill look into it
EDIT: I just wanna note that everything worked perfectly before i tried using threads to multithread this, when i had the PipelineFactory a PoolableTask object implementation, it could handle multiple connections etc and there was only the main thread calling 2 while loops handling everything in the whole server, i'm trying to spread out the load over the cpu but its not working out for me lol

Unsolvable reason behind Connection Timeout

Server Code
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
using Global;
using System.IO;
namespace Server
{
class Program
{
static List<string> BlackList = new List<string>();
static List<TcpClient> Clients = new List<TcpClient>();
static object _lock = new object();
static BinaryFormatter Formatter = new BinaryFormatter();
static TcpListener Server;
static void Main(string[] args)
{
Init();
Console.ReadLine();
}
/*
* Initiate the server and start listening
*/
static void Init()
{
Server = new TcpListener(IPAddress.Any, 7777);
Server.Start();
Task.Factory.StartNew(() => Listen());
}
/*
* Listens to new incoming connections
* Assigns the new client a worker who will listen to it's requests
* Add the client to the list of active clients
*/
static void Listen()
{
for (;;)
{
TcpClient client = Server.AcceptTcpClient();
lock(_lock)
Clients.Add(client);
Task.Factory.StartNew(() => Work(client));
Thread.Sleep(100);
}
}
/*
* Listens to incoming requests from a client and sends a response back if necessary
* On disconnect remove client from active clients list
*/
static void Work(TcpClient client)
{
while (client.Connected)
{
NetworkStream stream = client.GetStream();
try
{
dynamic request = Formatter.Deserialize(stream);
Response response = HandleRequest(request);
if(response != null)
Formatter.Serialize(stream, response);
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
}
lock (_lock)
Clients.Remove(client);
}
/*
* Handles File Transfer Requests
*/
static Response HandleRequest(FileTransferRequest request)
{
string file = request.File;
FileTransferResponse response;
if (File.Exists($"{Environment.CurrentDirectory}\\{file}"))
response = new FileTransferResponse(File.ReadAllBytes(file));
else
response = new FileTransferResponse(null);
return response;
}
}
}
Client Code
using System;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using Global;
using System.IO;
namespace Client
{
class Program
{
static TcpClient Server;
static void Main(string[] args)
{
string file = args[0];
string output = args[1];
Init();
NetworkStream stream = Server.GetStream();
BinaryFormatter formatter = new BinaryFormatter();
//Request
FileTransferRequest request = new FileTransferRequest(file);
formatter.Serialize(stream, request);
//Get Response
FileTransferResponse response = (FileTransferResponse) formatter.Deserialize(stream);
if (response.File == null)
Console.Write("File not found");
else
{
File.WriteAllBytes(output, response.File);
Console.Write("Success");
}
Console.ReadLine();
}
static void Init()
{
try
{
Server = new TcpClient("lordfrostbyte.webhop.me", 7777);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
Environment.Exit(-1);
}
}
}
}
Global Library Code
namespace Global
{
[Serializable]
public abstract class Request
{
}
[Serializable]
public class FileTransferRequest : Request
{
public string File;
public FileTransferRequest(string File)
{
this.File = File;
}
}
[Serializable]
public abstract class Response
{
}
[Serializable]
public class FileTransferResponse : Response
{
public byte[] File;
public FileTransferResponse(byte[] File)
{
this.File = File;
}
}
}
This is my code... It's not working !
But I have configured port forwarding
I have also disabled my firewall
My guess is something is wrong with windows. However I do not want to format my computer in order to solve this. I would much appreciate any input that would lead to solving this issue. I have had this issue for a while and I was wondering if anyone else has had a similar issue and if anyone has ever solved this. At the moment I have no clue how to even troubleshoot this issue. Do note that if I host the server on LAN and connect to LAN it works perfectly.
I had to reinstall pcap drivers.

named pipe client won't work in unity3d

I wrote this C# code to have namedPipeServer and NamedPipeClient, with Asynchronous read and write settings, connect to each other. Both code runs perfectly on visual studio 2010 that I am using with read and write working well without any application freeze during runtime.
But I want the client side running in unity3d. The problem I encounter is in client side code implemented in Unity3D. When I use Write_to_Server_Async(string message), read in the server side is not invoked and is only invoked when I quit Unity3d (I have end its process typically). I can tell something wrong with Unity3D, because the exact code works perfectly in visual studio, so I know my code is implemented the right way. I have heard about how unity3d does not really use real threads unless user manually creates one but even that has not solved the problem. My speculation is Unity3D developers might have created their version of .NET library 3.5 (sounds bizzare (does explain why they still haven't adopted 4.5)) or somehow they must have structured their library in a way that by default functions like NamedPipeClientStream.BeginWrite cannot create its own real thread. But then again I am not sure if its the problem with threads.
At the moment, I would like anyone to come up with good explanation.
Make sure to replace Debug.WriteLine to UnityEngine.Debug.Log in unity3d.
Below is Client Main method code and class
class PipeClient
{
private static Asynchronus_NamedPipe_Client client;
static void Main(string[] args)
{
client = new Asynchronus_NamedPipe_Client("mypipe7055");
while (client.Is_connected_to_server()) {
if (Console.ReadKey().Key == ConsoleKey.T)
{
client.Write_to_Server_Async("NEX CLIENT");
}
}
}
}
Asynchronus_NamedPipe_Client class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Security.Principal;
using System.Diagnostics;
using System.Threading;
namespace NamedPipes_CLIENT
{
public class Asynchronus_NamedPipe_Client
{
public readonly string pipe_address;
private System.IO.Pipes.NamedPipeClientStream clientStream;
public bool filter_message = true;
private string Server_Message = null;
public event ASYNC_pipe_status_callback ASYNC_external_Write_Completed;
public event ASYNC_pipe_status_callback ASYNC_external_Read_Completed;
public delegate void ASYNC_pipe_status_callback(string message);
private byte[] read_buffer = new byte[1024];
private byte[] write_buffer = new byte[1024];
private IAsyncResult read_result;
private IAsyncResult write_result;
private int read_id = 1;
public Asynchronus_NamedPipe_Client(string pipe_address)
{
try
{
this.pipe_address = pipe_address;
// if(clientStream.IsConnected){UnityEngine.Debug.Log("Server Already Running");}else{}
clientStream = new NamedPipeClientStream(".", this.pipe_address, PipeDirection.InOut, PipeOptions.Asynchronous);
clientStream.Connect(1);
if (clientStream.IsConnected)
{
Console.WriteLine("Connected to Server");
Read_from_Server_Async();
}
else { Console.WriteLine("Could NOT connect to Server"); }
}
catch (Exception oEX) { Console.WriteLine("Application Pipe Error: "+oEX.Message); }
}
public void Write_to_Server_Async(string message)
{
if (clientStream != null)
{
if (clientStream.CanWrite && clientStream.IsConnected)
{
clientStream.WaitForPipeDrain();
ASCIIEncoding.ASCII.GetBytes(message).CopyTo(write_buffer,0);
clientStream.BeginWrite(write_buffer, 0, write_buffer.Length, new AsyncCallback(Async_Write_Completed), 1);
} else { close_pipe(); }
}
}
public void Read_from_Server_Async()
{
if (clientStream.CanRead && clientStream.IsConnected)
{
clientStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(Async_Read_Completed), 2);
} else { close_pipe(); }
}
private void Async_Write_Completed(IAsyncResult result)
{
clientStream.EndWrite(result);
Debug.WriteLine("Written To Server => " + ASCIIEncoding.ASCII.GetString(write_buffer));
// close_pipe();
}
private void Async_Read_Completed(IAsyncResult result)
{
clientStream.EndRead(result);
Server_Message = ASCIIEncoding.ASCII.GetString(read_buffer);
this.Server_Message.Trim();
Console.WriteLine("Received from Server => " + Server_Message);
Debug.WriteLine("Received from Server => " + Server_Message);
if (clientStream.CanRead && clientStream.IsConnected)
{
Read_from_Server_Async();
}
else { close_pipe(); }
}
public Boolean Is_connected_to_server() {
return clientStream.IsConnected;
}
public void close_pipe()
{
if (clientStream != null)
{
if (clientStream.IsConnected)
{
clientStream.Close();
clientStream.Dispose();
Debug.WriteLine(" Pipe Closed");
}
}
}
}
}
Server side Main method implementation
static void Main(string[] args)
{
Asynchronus_NamedPipe_Server Async_server = new Asynchronus_NamedPipe_Server("mypipe7055");
while (true)
{
do
{
Async_server.Write_to_Client_Async("yeye");
Console.WriteLine("escape key");
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);
}
}
Server Side Class -----
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
using System.ComponentModel;
using System.Diagnostics;
namespace Application_Pipe
{
public class Asynchronus_NamedPipe_Server
{
public readonly string pipe_address;
private System.IO.Pipes.NamedPipeServerStream namedPipeServerStream;
private string Server_Message;
public delegate void ASYNC_pipe_status_callback(string message);
private byte[] read_buffer = new byte[1024];
private byte[] write_buffer = new byte[1024];
public Asynchronus_NamedPipe_Server(string pipe_address)
{
try
{
this.pipe_address = pipe_address;
namedPipeServerStream = new NamedPipeServerStream(this.pipe_address,
PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous); //new NamedPipeServerStream(pipe_address);
Console.WriteLine("Connecting to Client...");
namedPipeServerStream.WaitForConnection();
Console.WriteLine("Connected to Client");
Read_from_Client_Async();
}
catch (Exception oEX) { Console.WriteLine(oEX.Message); }
}
public void Write_to_Client_Async(string message)
{
if (namedPipeServerStream != null)
{
if (namedPipeServerStream.CanWrite && namedPipeServerStream.IsConnected)
{
namedPipeServerStream.WaitForPipeDrain();
ASCIIEncoding.ASCII.GetBytes(message).CopyTo(write_buffer,0);
namedPipeServerStream.BeginWrite(write_buffer, 0, write_buffer.Length, new AsyncCallback(Async_Write_Completed), 2);
}
else { close_pipe(); }
}
}
public void Read_from_Client_Async()
{
if (namedPipeServerStream != null)
{
if (namedPipeServerStream.CanRead && namedPipeServerStream.IsConnected)
{
namedPipeServerStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(Async_Read_Completed), 1);
} else { close_pipe(); }
}
}
private void Async_Read_Completed(IAsyncResult result)
{
namedPipeServerStream.EndRead(result);
this.Server_Message = ASCIIEncoding.ASCII.GetString(read_buffer);
this.Server_Message.Trim();
Debug.WriteLine("Received from Client => " + this.Server_Message+" <=REnd");
Read_from_Client_Async();
}
private void Async_Write_Completed(IAsyncResult result)
{
namedPipeServerStream.EndWrite(result);
Debug.WriteLine("Written To Client => " + ASCIIEncoding.ASCII.GetString(write_buffer));
}
public Boolean Is_connected_to_server()
{
return this.namedPipeServerStream.IsConnected;
}
public void close_pipe()
{
if(namedPipeServerStream.IsConnected){
namedPipeServerStream.Disconnect();
}
namedPipeServerStream.Close();
namedPipeServerStream.Dispose();
Debug.WriteLine(" Pipe Closed");
}
} //------class End
}

C# Console Auto Reconnect Server to Client

Hello Could anybody help me about this I'm trying to create client and server application reverse connection. When I tried to open the client and server I didn't encounter any problem vise versa. The scenario is I execute the client and the server but when I closed the server and re open again it doesn't accept any connection both connection lost.
Here is the Code:
CLIENT CODE:
namespace client1
{
class Program
{
public static bool isConnected { get; set; }
public static NetworkStream Writer { get; set; }
public static NetworkStream Reciever { get; set; }
static void Main(string[] args)
{
Connect_To_Server();
}
public static void Connect_To_Server()
{
TcpClient Connecting = new TcpClient();
string IP = "178.121.1.2";
while (isConnected == false)
{
try
{
Connecting.Connect(IP, 2000);
isConnected = true;
Writer = Connecting.GetStream();
Reciever = Connecting.GetStream();
Console.WriteLine("Connected: " + IP);
}
catch
{
Console.WriteLine("Error Connection... .");
Console.Clear();
}
}
Console.ReadKey();
}
}
}
SERVER CODE:
namespace server1
{
class Program
{
public static bool isConnected { get; set; }
public static NetworkStream Writer { get; set; }
static void Main(string[] args)
{
Listen_To_Client();
}
public static void Listen_To_Client()
{
TcpListener Listen = new TcpListener(2000);
while (true)
{
Listen.Start();
if (Listen.Pending())
{
TcpClient Connect = Listen.AcceptTcpClient();
isConnected = true;
Console.WriteLine("Connection Accepted");
Writer = Connect.GetStream();
Console.ReadKey();
}
}
}
}
}
Instead of using a local variable isConnected you should check for Connecting.Connected.
In your case you connect once and set isConnected to true. Now your while loop condition ends up as false and you never try to reconnect your client.
Edit:
while (true)
{
try
{
TcpClient client = new TcpClient(ip, port);
if (client.Connected)
{
// do something
client.close();
}
}
catch (SocketException) { }
Thread.Sleep(millisecs);
}
Bare in mind that you should not run this loop in your GUI thread since it has all sorts of blocking potential. Also only try to connect if you want to interact with the server. But for now this code should work for you.

Categories

Resources