I am trying to build a small program that checks for internet connection using while loop, quite new to C#, if possible could you help me figure out the problem with this program thanks.
var client = new WebClient();
while (true)
{
var stream =client.OpenRead("http://www.google.com").ToString();
Console.Write("You are in");
Console.ReadLine();
if (stream == "false")
{
Console.WriteLine("You are out");
break;
}
}
You may just send a Ping as following:
PingReply pingReply = new Ping().Send("http://www.google.com");
if (pingReply != null && pingReply.Status == IPStatus.Success)
{
// Internet is ok
}
This is sample code to check the internet connection. May be this will help you.
public static bool CheckInternetConnection()
{
try
{
using (var client = new WebClient())
{
using (var stream = client.OpenRead("http://www.google.com"))
{
return true;
}
}
}
catch
{
return false;
}
}
From the main call like this:
while (true)
{
if(CheckInternetConnection()==true){
Console.Write("You are in");
}
else{
Console.Write("You are out");
}
}
Related
I am working on my project in which i need arduinos to comunicate with my TCP server app. Eveyrthing was going fine as of now. But i just noticed that the server sometimes send invalid string to the client. (the string simply contains parts of the last string sent) Those the arduino doesnt know what to do with it.
How it should work:
Server receives: "CNN:1" (connection request from arduino #1)
Server sends: "CNN:1:CFM" (confirming that the request was recieved.
Server Recieves: "PING"
Server Sends: "PONG"
Server Recieves: "CHGTM:1:B" (arduino #1 sends request to change team to Blue)
Server Sends: "CHGTM:1:B:CFM" or "CHGTM:1:GMPAUSED" (depends on wheter the game is running or is paused)
EXAMPLE OF THE BAD BEHAVIOUR:
Server Recieves: "CNN:1"
sends: "CNN:1:CFM"
Recieves: "PING"
Sends: "PONG1:CFM" (This message contains part of the last message those is corrupted -- It doesnt happen everytime only sometimes)
Do anybody know how to fix this? I tried nulling the string variables used to contain the text before sending but no luck. I also tried flushing the networkstream after writing to it but also no luck (as i understand it, this method is just placeholder and doesnt do anything at the moment)
Here is the code that i am using for the communication:
class Comunication
{
TcpListener server = null;
public List<Majak> activeClients;
public MainWindow mw { get; set; }
public bool isConOk { get; set; }
public Comunication(string ip, int port, MainWindow _mw)
{
mw = _mw;
activeClients = new List<Majak>();
IPAddress localAddr = IPAddress.Parse(ip);
server = new TcpListener(localAddr, port);
server.Start();
StartConnectionCheck();
StartListener();
//StartConnectionCheck();
}
public void StartListener()
{
try
{
while (true)
{
TcpClient client = server.AcceptTcpClient();
if(client != null)
{
Majak m = new Majak(client);
Thread t = new Thread(new ParameterizedThreadStart(HandleDevice));
t.Start(m);
activeClients.Add(m);
}
}
}
catch(SocketException e)
{
MessageBox.Show("Nelze spustit server", e.ToString());
server.Stop();
}
}
public void HandleDevice(Object obj)
{
Majak majak = (Majak)obj;
if (majak != null && majak.isConnected)
{
var stream = majak.Client.GetStream();
string imei = String.Empty;
string data = null;
Byte[] bytes = new Byte[256];
int i;
try
{
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
string hex = BitConverter.ToString(bytes);
data = Encoding.ASCII.GetString(bytes, 0, i); //text revieved from arduino needs evaluation
DataEvaluation(data, majak);
}
}
catch (Exception e) //if there is an error than the client is closed and removed from list of connected clients and this thread is stopped
{
//MessageBox.Show(e.ToString(), "Chyba při komunikaci s majákem");
App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
{
activeClients.Remove(majak);
});
majak.isConnected = false;
majak.Client.Close();
return;
}
}
}
public void DataEvaluation(string d, Majak m)
{
//split data by ":"
string[] datasplt = d.Split(':');
switch(datasplt[0]){
case "CNN":
m.ID = int.Parse(datasplt[1]);
SendResponse(1, m);
break;
case "PONG":
isConOk = true;
break;
case "PING":
SendResponse(3, m);
break;
case "CHGTM":
m.Color = datasplt[2];
if(mw.SS.ChangeTeam(int.Parse(datasplt[1]), datasplt[2]))
{
SendResponse(2, m); //if the game is running than sends confirmation to the arduino
}
else
{
SendResponse(4, m); //if the game is paused sends to arduino string saying so
}
break;
}
}
public void SendResponse(int i, Majak m)
{
string response = null;
Byte[] response_byte = null;
switch (i)
{
case 1: //connection cofirmation
//connection validation
response = null;
response = string.Format("CNN:{0}:CFM", m.ID);
response_byte = null;
response_byte = System.Text.Encoding.ASCII.GetBytes(response);
try
{
m.Client.GetStream().Write(response_byte, 0, response_byte.Length);
m.Client.GetStream().Flush();
}
catch { }
break;
case 2: //change team confirmation
//confirms change of team
response = null;
response = string.Format("CHGTM:{0}:{1}:CFM", m.ID, m.Color);
response_byte = null;
response_byte = System.Text.Encoding.ASCII.GetBytes(response);
try
{
m.Client.GetStream().Write(response_byte, 0, response_byte.Length);
m.Client.GetStream().Flush();
}
catch { }
break;
case 3: //Sends PONG if PING is recieved
response = null;
response = "PONG";
response_byte = null;
response_byte = System.Text.Encoding.ASCII.GetBytes(response);
try
{
m.Client.GetStream().Write(response_byte, 0, response_byte.Length);
m.Client.GetStream().Flush();
}
catch { }
break;
case 4:
response = null;
response = string.Format("CHGTM:{0}:GMPAUSED", m.ID);
response_byte = null;
response_byte = System.Text.Encoding.ASCII.GetBytes(response);
try
{
m.Client.GetStream().Write(response_byte, 0, response_byte.Length);
m.Client.GetStream().Flush();
}
catch { }
break;
}
}
public void StartConnectionCheck()
{
Thread t = new Thread(new ParameterizedThreadStart(CheckConnectionStatus));
t.Start(mw);
}
public void CheckConnectionStatus(Object __mw) //every 30 seconds sends PING to the arduino in order to evaluate if the connection still exists. If the PONG is not recieved in 30 seconds than closes connection and remove client from connected clients
{
while (true)
{
string pingmsg = "PING";
Byte[] pingmsg_byte = System.Text.Encoding.ASCII.GetBytes(pingmsg);
Stopwatch s = new Stopwatch();
foreach (Majak m in activeClients.ToList<Majak>())
{
isConOk = false;
var stream = m.Client.GetStream();
Byte[] bytes = new Byte[256];
try
{
stream.Write(pingmsg_byte, 0, pingmsg_byte.Length);
s.Restart();
while (s.Elapsed < TimeSpan.FromSeconds(30) && !isConOk)
{
}
if (!isConOk)
{
m.isConnected = false;
activeClients.Remove(m);
m.Client.GetStream().Close();
m.Client.Close();
}
}
catch (Exception e)
{
m.isConnected = false;
activeClients.Remove(m);
m.Client.Close();
}
}
Thread.Sleep(30000);
}
}
}
I'm trying to port my code from an obsolete library called CastleMQ to NetMQ but I'm running into some problems.
I prefer to using polling with a timeout, for reliability - I just found that it worked best for me from trial and error compared to just sitting blocking the port indefinitely.
here is my CastleMQ code
public int ZeroPort;
private void ThreadProc()
{
var ctx = new Context();
try {
using (var repSocket = ctx.CreateSocket(SocketType.Rep))
{
string bindAddress = "tcp://*:"+ZeroPort;
repSocket.Bind(bindAddress);
print2("*** BINDING on {0} ***", bindAddress);
bool quit = false;
while (!quit) {
try {
var polling = new Polling(PollingEvents.RecvReady, repSocket);
polling.RecvReady += (socket) =>
{ // using socket.Recv() here is guaranted to return stuff
var msg = socket.Recv();
var msgStr = Encoding.UTF8.GetString(msg);
print2("[REP:{0}] {1}", bindAddress, msgStr);
switch (msgStr) {
case "positions": {
StringBuilder csv = new StringBuilder();
print2("csv: {0}", csv.ToString());
socket.Send(csv.ToString());
break;
}
default: {
socket.Send("Unrecognized Command: " + msgStr);
break;
}
}
};
polling.Poll(POLL_TIMEOUT_MS); // this returns once some socket event happens
} catch (Exception e) {
if (e is ThreadAbortException) {
quit = true;
print2("\n*** EXITED ***");
} else print2(e.ToString());
}
}
}
} catch (Exception e) {
print2(e.ToString());
} finally {
ctx.Dispose();
}
}
here is what I tried to do and then got lost with NetMQ
private void ThreadProc()
{
try {
string bindAddress = "#tcp://*:" + ZeroPort;
print2("*** BINDING on {0} ***", bindAddress);
using (var repSocket = new ResponseSocket(bindAddress))
using (var poller = new NetMQPoller { repSocket })
{
// bool quit = false;
// while (!quit)
// these event will be raised by the Poller
repSocket.ReceiveReady += (s, a) =>
{
// receive won't block as a message is ready
string msg = a.Socket.ReceiveString(); // defeinition for ReceiveString() can't be found
// send a response
a.Socket.Send("Response"); // it doesn't like "Response", do I need to wrap it in some object?
I'm especially confused as how to add a timeout so I can poll with a timeout in a loop the way my CastleMQ code does.
Any pointers would be much appreciated, thanks
I have server in c#, client in PHP. I used Supersocket[https://supersocket.codeplex.com/] to communication between client and server.
C# with Supersocket - Serverside
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase;
using SuperSocket.Common;
using SuperSocket.SocketEngine;
using SuperSocket;
using System.Configuration;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press any key to start the WebSocketServer!");
Console.ReadKey();
Console.WriteLine();
var appServer = new AppServer();
//Setup the appServer
if (!appServer.Setup(2020))
{
Console.WriteLine("Failed to setup!");
Console.ReadKey();
return;
}
appServer.NewSessionConnected += new SessionHandler<AppSession>(appServer_NewSessionConnected);
appServer.NewRequestReceived += new RequestHandler<AppSession, SuperSocket.SocketBase.Protocol.StringRequestInfo>(appServer_NewRequestReceived);
appServer.SessionClosed += new SessionHandler<AppSession, CloseReason>(appServer_SessionClosed);
Console.WriteLine();
//Try to start the appServer
if (!appServer.Start())
{
Console.WriteLine("Failed to start!");
Console.ReadKey();
return;
}
Console.WriteLine("The server started successfully, press key 'q' to stop it!");
while (Console.ReadKey().KeyChar != 'q')
{
Console.WriteLine();
continue;
}
//Stop the appServer
appServer.Stop();
Console.WriteLine();
Console.WriteLine("The server was stopped!");
Console.ReadKey();
}
static void appServer_NewSessionConnected(AppSession session)
{
session.Send("Swelcome");
}
static void appServer_SessionClosed(AppSession session, CloseReason value)
{
session.Send("Server: " + "welcome");
}
static void appServer_NewRequestReceived(AppSession session, SuperSocket.SocketBase.Protocol.StringRequestInfo requestInfo)
{
try
{
switch (requestInfo.Key.ToUpper())
{
case ("ECHO"):
session.Send(requestInfo.Body);
break;
case ("ADD"):
session.Send(requestInfo.Parameters.Select(p => Convert.ToInt32(p)).Sum().ToString());
break;
case ("MULT"):
var result = 1;
foreach (var factor in requestInfo.Parameters.Select(p => Convert.ToInt32(p)))
{
result *= factor;
}
session.Send(result.ToString());
break;
default:
Console.WriteLine("Default");
session.Send(requestInfo.Body);
break;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
PHP Code - Client side
class XoneDataReciver
{
var $socketPtr;
function OpenConnection($server, $port)
{
$this->socketPtr = fsockopen($server, $port, $errno, $errstr, 0.4);
if (!$this->socketPtr) {
echo "Network down. Please refresh the page again or try again later."; exit();
} else {
return 0;
}
}
function MakeRequest($action, $params = array())
{
if (!$this->socketPtr)
return "error";
$this->sendRequest($action); //Error - Client closing
return $this->readAnswer(); // Got msg from server
}
function sendRequest($request)
{
fputs($this->socketPtr, $request);
}
}
$xone_ip ="127.0.0.1";
$xone_port = "2020";
$xonerequest = new XoneDataReciver;
$xonerequest->OpenConnection($xone_ip, $xone_port);
?>
I got msg from server to client(PHP). But when I try to send msg from php to c#, SessionClosed event fire and the error shows "Client closing". Anyone help me to communicate php client to c# server via Supersocket. Thanks in advance.
Increasing the MaxConnectionNumber in server configuration worked for me.
I connect to my (C#) server and from an App built in Corona SDK but for the second person can never connect.
I have tried using different IP's i.e. two cellphones with external IP's with no difference.
This is how my server listener works:
server.cs
void Listener()
{
while (isRunning)
{
try
{
Socket socket = listener.AcceptSocket();
foreach (var worker in workers)
if (worker.IsAvailable)
{
worker.ProcessNewSocket(socket);
break;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
public void Run()
{
Console.WriteLine("Server.Run()");
listener.Start();
isRunning = true;
foreach (var worker in workers)
{
Thread t = new Thread(worker.Run);
t.Start();
}
Listener();
}
ServerWorker.cs
public void ProcessNewSocket(Socket socket)
{
var pc = new PlayerClient(this);
sockets.Add(socket, pc);
}
// this method will be called in cycle
public void Run()
{
while (server.IsRunning)
{
List<Socket> readList = sockets.Keys.ToList(); //List of sockets that have some data from client available for reading.
List<Socket> writeList = sockets.Keys.ToList(); //List of sockets that are ready to write (send) to the client. An action was made to a table and the change was sent to PlayerClient.Write and is now stored in the queue (MemoreStream)
List<Socket> errorList = sockets.Keys.ToList();
if (readList.Count() != 0 || writeList.Count() != 0 || errorList.Count() != 0)
{
// for providing security you can use System.Net.Security.SslStream here when read/write data,
// see http://msdn.microsoft.com/ru-ru/library/system.net.security.sslstream(v=vs.110).aspx
Socket currentSocket = null;
// foreach socket with events
try
{
foreach (var s in readList)
{
currentSocket = s;
//TODO: Get the actual length of the message.
byte[] data = new byte[2048];
s.Receive(data);
sockets[s].OnData(data);
}
foreach (var s in writeList)
{
currentSocket = s;
if (sockets[s].IsWriteDataAvailable())
{
s.Send(sockets[s].GetWriteBuffer());
sockets[s].ClearWriteBuffer();
}
}
foreach (var s in errorList)
{
//OnError
}
}
// we got exception, depending on the type...
catch (SocketException ex)
{
//Console.WriteLine(ex.ToString());
// send client error message, this is not always possible(for example network failure)
// maybe we would like to notify his opponent about connection failure
// terminate connection
if (ex.ErrorCode == (int)SocketError.ConnectionAborted || ex.ErrorCode == (int)SocketError.ConnectionReset)
RemoveSocket(currentSocket);
else
Console.WriteLine("Other problem .. " + ex.ErrorCode.ToString());
}
}
}
}
I'm new in network programming so I'm not really sure what to do. I have read about using ASync but first I would like to know if there is something I can do with this code and/or if I should change it completely?
I think the "BREAK" statement in your Listener() Block;
foreach (var worker in workers)
if (worker.IsAvailable)
{
worker.ProcessNewSocket(socket);
break; // this BREAK WILL END YOUR loop AFTER first CLIENT FOUND.
}
So, try removing break as;
foreach (var worker in workers)
{
if (worker.IsAvailable)
{
worker.ProcessNewSocket(socket);
}
}
This is one of my first issues. Whenever I exit out the program, tcpClient.Connect() takes forever to close. I've tried a ton of things, and none of them seem to work.
Take a look at the CreateConnection() thread, if the client isn't connected yet... and I close the program, it takes forever to close. If it IS connected, it closes immediately. I know this can be done with some kind of timeout trick, but i've tried a few and none of them worked.
Please provide a code example if you can.
Also, is there any good tutorial out there for C# on reading/writing the actual bytes with a buffer instead of this version that just does masterServer.writeLine() and masterServer.readline() or are they both just as efficient?
If you see anything else to help me improve this... by all means, go ahead. I'm trying to teach myself how to do this and I have no help, so don't let me go on doing something wrong if you see it!!! Thanks guys!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace RemoteClient
{
public partial class Form1 : Form
{
private int MyPort = 56789;
private IPAddress myIp = IPAddress.Parse("210.232.115.79");
private IPAddress serverIp = IPAddress.Parse("72.216.18.77"); // Master Server's IP Address
public static TcpClient masterServer = new TcpClient();
private StreamWriter responseWriter;
private StreamReader commandReader;
private Thread connectionThread;
private Thread commandsThread;
private bool RequestExitConnectionThread { get; set; }
private delegate void AddMessageDelegate(string message, int category);
private delegate void ConnectedDelegate();
private bool isConnected { get; set; }
public Form1()
{
InitializeComponent();
isConnected = false;
}
private void LogMessage(string message, int category)
{
if (category == 1)
{
ListViewItem item = new ListViewItem(message);
item.BackColor = Color.LightGreen;
item.UseItemStyleForSubItems = true;
Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString());
}
if (category == 2)
{
ListViewItem item = new ListViewItem(message);
item.BackColor = Color.Orange;
item.UseItemStyleForSubItems = true;
Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString());
}
if (category == 3)
{
ListViewItem item = new ListViewItem(message);
item.BackColor = Color.Yellow;
item.UseItemStyleForSubItems = true;
Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString());
}
if (category == 0)
{
Log.Items.Add(message).SubItems.Add(DateTime.Now.ToString());
}
}
private void Connected()
{
LogMessage("Found and Accepted Master Server's connection. Waiting for reply...",1);
Status.Text = "Connected!";
Status.ForeColor = Color.Green;
commandsThread = new Thread(new ThreadStart(RecieveCommands));
sendClientInfo();
}
private void exitButton_Click(object sender, EventArgs e)
{
Disconnect();
exitButton.Enabled = false;
exitButton.Text = "Closing...";
if (connectionThread != null)
{
while (connectionThread.IsAlive)
{
Application.DoEvents();
}
}
this.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
Connect();
}
private void Disconnect()
{
RequestExitConnectionThread = true;
if (masterServer != null)
masterServer.Close();
if (connectionThread != null)
connectionThread.Abort();
LogMessage("Closing Client. Please wait while Program threads end.", 2);
}
private void Disconnected()
{
Status.Text = "Disconnected";
Status.ForeColor = Color.Red;
Connect();
}
private void Connect()
{
LogMessage("Attempting to connect to Master Server...", 1);
connectionThread = new Thread(new ThreadStart(CreateConnection));
connectionThread.Start();
}
private void CreateConnection()
{
int i = 1;
bool success = false;
while (!success)
{
try
{
using (masterServer = new TcpClient())
{
IAsyncResult result = masterServer.BeginConnect(serverIp, MyPort, null, null);
success = result.AsyncWaitHandle.WaitOne(1000, false);
}
if (success)
{
BeginInvoke(new ConnectedDelegate(this.Connected), new object[] {});
break;
}
else
{
Thread.Sleep(2000);
BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Connection Retry # " + i.ToString() + ". Master Server hasn't been started yet.", 3 });
}
}
catch
{
MessageBox.Show("Error!");
}
i++;
}
}
private void RecieveCommands()
{
MessageBox.Show("Hello!");
commandReader = new StreamReader(masterServer.GetStream());
string CommandResponse = commandReader.ReadLine();
string Command = null;
if (CommandResponse != null)
MessageBox.Show("Recieved Command that was NOT null!");
if (CommandResponse != null)
{
MessageBox.Show("Recieved null response!");
BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Disconnected From Master Server. Reason: Recieved Null response.", 1 });
Disconnected();
}
else if (CommandResponse.StartsWith("0"))
{
MessageBox.Show("Recieved 0 as a response!");
Command = CommandResponse.Substring(2).Trim();
isConnected = false;
BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Disconnected From Master Server. Reason: " + Command, 1 });
}
else if (CommandResponse.StartsWith("1"))
{
MessageBox.Show("Recieved 1 as a response!");
isConnected = true;
BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Connected to Master Server Successfully.", 1 });
}
}
//************************** RESPONSE'S BELOW HERE ************************* \\
private void sendClientInfo()
{
responseWriter = new StreamWriter(masterServer.GetStream());
responseWriter.WriteLine(myIp.ToString());
responseWriter.Flush();
}
}
}
Sorry, after testing it: NO, it does not use an async waithandle, it blocks the process :(
I prefer this solution, which also blocks the process but only by the period you specify, in this case 5 seconds:
using (TcpClient tcp = new TcpClient())
{
IAsyncResult ar = tcp.BeginConnect("127.0.0.1", 80, null, null);
System.Threading.WaitHandle wh = ar.AsyncWaitHandle;
try
{
if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false))
{
tcp.Close();
throw new TimeoutException();
}
tcp.EndConnect(ar);
}
finally
{
wh.Close();
}
}
From: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/2281199d-cd28-4b5c-95dc-5a888a6da30d
The following example uses both async connection and async timeout control:
var tcp = new TcpClient();
var ar = tcp.BeginConnect(Ip, Port, null, null);
Task.Factory.StartNew(() =>
{
var wh = ar.AsyncWaitHandle;
try
{
if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false))
{
// The logic to control when the connection timed out
tcp.Close();
throw new TimeoutException();
}
else
{
// The logic to control when the connection succeed.
tcp.EndConnect(ar);
}
}
finally
{
wh.Close();
}
});
connect with timeout of 2000 ms:
AutoResetEvent connectDone = new AutoResetEvent( false );
TcpClient client = new TcpClient();
client.BeginConnect(
"127.0.0.1", 80,
new AsyncCallback(
delegate( IAsyncResult ar ) {
client.EndConnect( ar );
connectDone.Set();
}
), client
);
if( !connectDone.WaitOne( 2000 ) ) {
Console.WriteLine( "network connection failed!" );
Environment.Exit( 0 );
}
Stream stream = client.GetStream();
Adding a check within your connection process to cancel it if the program is exiting should help.
Try adding this in CreateConnection() inside your while(!success) loop but before your try block:
if(RequestExitConnectionThread)
{
break;
}
Here's an example of an asynchronous BeginConnect() call:
myTcpClient.BeginConnect("localhost", 80, OnConnect, null);
OnConnect function:
public static void OnConnect(IAsyncResult ar)
{
// do your work
}