Telnet/TcpClient C# Skipping Code and not iterating through loop - c#

this is going to sound silly but for some reason this code seems to skip over the read. Or maybe it is going too fast? I'm trying to get a telnet response from the server and I get the first line response but nothing more. It doesn't matter how many readline() I put or if I try to sleep the thread. What can I do to get the whole response from the server to be printed? I think I narrowed the problem down to exiting. In the sample program if you hard code the exit, it immediately ends the loop and displays nothing. I tried sleeping the thread but that just seemed to stop everything.
Output:
220 server-12.tower-558.messagelabs.com ESMTP
Expected Output:
250-server-11.tower-555.messagelabs.com says EHLO to iphere
250-PIPELINING
250-8BITMIME
250-STARTTLS
My Code:
//Telnet Start
IPHostEntry hostInfo = Dns.Resolve(list[j]);
TelnetConnection tc = new TelnetConnection(hostInfo.AddressList[0].ToString(), 25);
string prompt = "a";
string consoleout = "";
// while connected
while (tc.IsConnected && prompt != "exit")
{
// display server output
prompt = "ehlo a.com";
tc.WriteLine(prompt);
//I've tried adding a 2 or 5 second thread sleep here and I still get the same result.
Console.Write(tc.Read());
prompt = "exit";
}
//Telnet End
TelnetConnection Class:
// minimalistic telnet implementation
// conceived by Tom Janssens on 2007/06/06 for codeproject
//
// http://www.corebvba.be
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
namespace MinimalisticTelnet
{
enum Verbs {
WILL = 251,
WONT = 252,
DO = 253,
DONT = 254,
IAC = 255
}
enum Options
{
SGA = 3
}
class TelnetConnection
{
TcpClient tcpSocket;
int TimeOutMs = 100;
public TelnetConnection(string Hostname, int Port)
{
try
{
tcpSocket = new TcpClient(Hostname, Port);
}
catch (SocketException e)
{
Console.Write(e);
}
}
public string Login(string Username,string Password,int LoginTimeOutMs)
{
int oldTimeOutMs = TimeOutMs;
TimeOutMs = LoginTimeOutMs;
string s = Read();
if (!s.TrimEnd().EndsWith(":"))
throw new Exception("Failed to connect : no login prompt");
WriteLine(Username);
s += Read();
if (!s.TrimEnd().EndsWith(":"))
throw new Exception("Failed to connect : no password prompt");
WriteLine(Password);
s += Read();
TimeOutMs = oldTimeOutMs;
return s;
}
public void WriteLine(string cmd)
{
Write(cmd + "\n");
}
public void Write(string cmd)
{
if (!tcpSocket.Connected) return;
byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(cmd.Replace("\0xFF","\0xFF\0xFF"));
tcpSocket.GetStream().Write(buf, 0, buf.Length);
}
public string Read()
{
if (!tcpSocket.Connected) return null;
StringBuilder sb=new StringBuilder();
do
{
ParseTelnet(sb);
System.Threading.Thread.Sleep(TimeOutMs);
} while (tcpSocket.Available > 0);
return sb.ToString();
}
public bool IsConnected
{
get { return tcpSocket.Connected; }
}
void ParseTelnet(StringBuilder sb)
{
while (tcpSocket.Available > 0)
{
int input = tcpSocket.GetStream().ReadByte();
switch (input)
{
case -1 :
break;
case (int)Verbs.IAC:
// interpret as command
int inputverb = tcpSocket.GetStream().ReadByte();
if (inputverb == -1) break;
switch (inputverb)
{
case (int)Verbs.IAC:
//literal IAC = 255 escaped, so append char 255 to string
sb.Append(inputverb);
break;
case (int)Verbs.DO:
case (int)Verbs.DONT:
case (int)Verbs.WILL:
case (int)Verbs.WONT:
// reply to all commands with "WONT", unless it is SGA (suppres go ahead)
int inputoption = tcpSocket.GetStream().ReadByte();
if (inputoption == -1) break;
tcpSocket.GetStream().WriteByte((byte)Verbs.IAC);
if (inputoption == (int)Options.SGA )
tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WILL:(byte)Verbs.DO);
else
tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WONT : (byte)Verbs.DONT);
tcpSocket.GetStream().WriteByte((byte)inputoption);
break;
default:
break;
}
break;
default:
sb.Append( (char)input );
break;
}
}
}
}
}
UPDATE:
Using the following loop I was able to get it to work once, but only once it would not iterate through the count of j when I verified that j was 2. My output, expected output and function are below.
Function:
for (int j = 0; j < list.Count; j++)
{
//Telnet Start
Console.WriteLine("On round #" + j);
IPHostEntry hostInfo = Dns.Resolve(list[j]);
TelnetConnection tc = new TelnetConnection(hostInfo.AddressList[0].ToString(), 25);
string prompt = "a";
string consoleout = "";
// while connected
while (tc.IsConnected && prompt != "exit")
{
// display server output
Console.Write(tc.Read());
// send client input to server
prompt = "ehlo a.com";
tc.WriteLine(prompt);
// display server output
consoleout = tc.Read();
Console.Write(consoleout);
//send exit input to server
prompt = "exit";
tc.WriteLine(prompt);
Console.Write(tc.Read());
}
Console.WriteLine("**DISCONNECTED**");
//Telnet End
if (consoleout.IndexOf("STARTTLS")>-1)
{
if (j == 0)
{
if (list[j].Contains(domains[i]))
dataGridView1.Rows.Add(domains[i], list[j], "Y", numberemployees, "Y");
else
dataGridView1.Rows.Add(domains[i], list[j], "Y", numberemployees, "N");
}
else
{
if (list[j].Contains(domains[i]))
dataGridView1.Rows.Add(null, list[j], "Y", null, "Y");
else
dataGridView1.Rows.Add(null, list[j], "Y", null, "N");
}
}
else
{
if (j == 0)
{
if (list[j].Contains(domains[i]))
dataGridView1.Rows.Add(domains[i], list[j], "N", numberemployees, "Y");
else
dataGridView1.Rows.Add(domains[i], list[j], "N", numberemployees, "N");
}
else
{
if (list[j].Contains(domains[i]))
dataGridView1.Rows.Add(null, list[j], "N", null, "Y");
else
dataGridView1.Rows.Add(null, list[j], "N", null, "N");
}
}
}
Output:
On round #0
True220 server-6.tower-95.messagelabs.com ESMTP
250-server-6.tower-95.messagelabs.com
250-STARTTLS
250-PIPELINING
250 8BITMIME
502 unimplemented (#5.5.1)
**DISCONNECTED**
On round #1
True220 server-14.tower-558.messagelabs.com ESMTP
**DISCONNECTED**
Expected Output:
On round #0
True220 server-6.tower-95.messagelabs.com ESMTP
250-server-6.tower-95.messagelabs.com
250-STARTTLS
250-PIPELINING
250 8BITMIME
502 unimplemented (#5.5.1)
**DISCONNECTED**
On round #1
True220 server-14.tower-558.messagelabs.com ESMTP
250-STARTTLS
250-PIPELINING
250 8BITMIME
**DISCONNECTED**
So for whatever reason, it simply won't do the second loop. But it also is starting to depend on the server. Some servers respond with a little information and some I get something like this, which makes it look like nothing happened at all.
On round #0
True220 SMTP Proxy Server Ready
**DISCONNECTED**
On round #1
True220 SMTP Proxy Server Ready
**DISCONNECTED**
On round #2
True220 SMTP Server Ready
**DISCONNECTED**
On round #3
True220 SMTP Server Ready
**DISCONNECTED**
On round #4
True220 SMTP Proxy Server Ready
**DISCONNECTED**
On round #5
True220 SMTP Proxy Server Ready
**DISCONNECTED**

Kyle,
It looks like you need to open the socket:
public string Read()
{
if (!tcpSocket.Connected)
{
throw new Exception("Socket is Closed.");
}
StringBuilder sb=new StringBuilder();
do
{
ParseTelnet(sb);
System.Threading.Thread.Sleep(TimeOutMs);
} while (tcpSocket.Available > 0);
return sb.ToString();
}
It isn't open, so it is returning.
[UPDATE]
Try looping through IPHostEntry hostInfo = Dns.Resolve(list[j]); before your //Telnet Start comment:
private const int PORT25 = 25; // I hate magic numbers
foreach (var item in list) {
var hostInfo = Dns.Resolve(item);
Console.WriteLine(hostInfo);
foreach (var address in hostInfo.AddressList) {
var tc = new TelnetConnection(address, PORT25);
Console.WriteLine("{0} TelnetConnection Connected: {1}", address, tc.IsConnected);
}
}
[Update 2]
This is really hard to debug, not knowing what all you are trying to connect to and what else is going on.
That said, let's try the following:
In your class MinimalisticTelnet, add this method:
public void Close() {
if (tcpSocket != null) {
tcpSocket.Close();
}
}
I don't see it anywhere else, and that could be causing some issues the next time you attempt your second connection.
Now, in your test code, add the new one line of code after the while loop:
while (tc.IsConnected && prompt != "exit") {
// display server output
Console.Write(tc.Read());
// send client input to server
prompt = "ehlo a.com";
tc.WriteLine(prompt);
// display server output
consoleout = tc.Read();
Console.Write(consoleout);
//send exit input to server
prompt = "exit";
tc.WriteLine(prompt);
Console.Write(tc.Read());
}
tc.Close();
Console.WriteLine("**DISCONNECTED**");
With any luck, the reason your 2nd connection was failing was because you still had an open connection.

I solve a so similar problem adding 3 reads, then 8 seconds timeout and finally reading again AND SHOWING IN MY RICHTEXBOX:
string r1 = conexion.Read();
string r2 = conexion.Read();
string r3 = conexion.Read();
System.Threading.Thread.Sleep(8000);
richtextbox.AppendText(r1 + r2 + r3);
I hope it can help you!
Tell me if it works to you.

Related

C# function that waits for serial port ready before reading

I have a system in which I read the serial port from a X,Y,Z motion stage, meaning that I send a signal (via usb) to a function which reads the signal, moves a stepper motor accordingly, then reads the next stepper motor signal and so on. At the moment, this function looks like this:
public void SCPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
string sCurString = "";
//Loop to receive the data from serial port
System.Threading.Thread.Sleep(150);
sCurString = SCPort.ReadExisting();
if (sCurString != "")
StrReceiver = sCurString;
if (BlnSet == true)
{
if (StrReceiver.Length == 3)
{
if (StrReceiver.Substring(StrReceiver.Length - 3) == "OK\n")
BlnReadCom = true;
}
else if (StrReceiver.Length == 4)
{
if (StrReceiver.Substring(StrReceiver.Length - 3) == "OK\n" || StrReceiver.Substring(StrReceiver.Length - 4) == "OK\nS")
BlnReadCom = true;
}
else
{
if (StrReceiver.Substring(StrReceiver.Length - 3) == "OK\n" || StrReceiver.Substring(StrReceiver.Length - 4) == "OK\nS" ||
StrReceiver.Substring(StrReceiver.Length - 5) == "ERR1\n" || StrReceiver.Substring(StrReceiver.Length - 5) == "ERR3\n" ||
StrReceiver.Substring(StrReceiver.Length - 5) == "ERR4\n" || StrReceiver.Substring(StrReceiver.Length - 5) == "ERR5\n")
BlnReadCom = true;
}
}
else
{
if (StrReceiver.Substring(StrReceiver.Length - 1, 1) == "\n")
BlnReadCom = true;
}
}
catch (Exception ex)
{
MessageBox.Show("Failed to receive data", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
This function reads the serialport SCPort, every 150ms indicated by the Thread.Sleep. If I try to read the data any faster, I get the exception (which is likely an indication of the limitation of my system). Fine. However, this exception is not thrown immediately, but every once in a while. What I would like to do instead of waiting a fixed time between reading the signal, is to each time wait until the serialport is ready and then read it. This should speed up my system, as instead of waiting 150ms between every movement, I could wait exactly the amount of time the system requires.
The question is: how do I implement this behavior in the function?
I have not tried to solve it on my own, because I really have no idea about how to do this. Will be happy to implement this into my function, but at a bare minimum I need to be pointed in the right direction.
This function handles connection to the port SCPort.
public void ConnectPort(short sPort)
{
if (SCPort.IsOpen == true)
{
ClosePort();
buttonConnectStage.Text = "Connect stage";
}
else if (SCPort.IsOpen == false)
{
SCPort.PortName = comStage.SelectedItem.ToString(); //Set the serial port number
SCPort.BaudRate = 9600; //Set the bit rate
SCPort.DataBits = 8; //Set the data bits
SCPort.StopBits = StopBits.One; //Set the stop bit
SCPort.Parity = Parity.None; //Set the Parity
SCPort.ReadBufferSize = 2048;
SCPort.WriteBufferSize = 1024;
SCPort.DtrEnable = true;
SCPort.Handshake = Handshake.None;
SCPort.ReceivedBytesThreshold = 1;
SCPort.RtsEnable = false;
//This delegate should be a trigger event for fetching data asynchronously, it will be triggered when there is data passed from serial port.
SCPort.DataReceived += new SerialDataReceivedEventHandler(SCPort_DataReceived); //DataReceivedEvent delegate
try
{
SCPort.Open(); //Open serial port
if (SCPort.IsOpen)
{
StrReceiver = "";
BlnBusy = true;
BlnSet = false;
SendCommand("?R\r"); //Connect to the controller
Delay(250);
BlnBusy = false;
if (StrReceiver == "?R\rOK\n")
{
displayValues();
BlnConnect = true; //Connected successfully
ShrPort = sPort; //Setial port number
buttonConnectStage.Text = "Disconnect stage";
SendCommand("V" + sSpeed.ToString() + "\r"); //Set speed
}
else
{
BlnBusy = false;
BlnConnect = false;
buttonConnectStage.Text = "Failed to connect";
MessageBox.Show("Failed to connect", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
}
}
catch (Exception ex)
{
}
}
}

C# Why is Serial.WriteLine() so slow?

When I want to program a Teensy 3.5 micro-controller, I send it a .HEX file via a hardware serial port. I have two ways of doing this; one way is to use a serial comms app like Tera Term to send the file, and another way is via a small C# command-line app I wrote to do the same thing.
When I send a 3000+ line Hex file to the micro-controller, it takes approximately 14 seconds. When I do the same thing with my C# program, it takes twice as long (or longer!). The baud rate for both Tera Term and my C# program are the same, and of course the Teensy setup is common to both.
When I looked as the serial transfer using a digital scope, I see the following (same time scale in both photos):
The first photo shows the transfer when using Tera Term, and the second one shows the transfer when using my C# program using Serial.WriteLine() to transfer file contents line-by-line, as shown below:
using System;
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Timers;
using System.Diagnostics;
/*
Small console app to facilitate over-the-air (OTA) updates to a Teensy 3.x/4.x controller,
using VS2019 with the Visual Micro extension as the Arduino IDE. It is called by a post-build
'hook' statement in a file called 'board.txt' located in whatever Teensy program is
being updated. This app does the following:
- Extract the project path and selected COMPORT number from the arguments to the call to Main()
- Opens a UART serial port connection to the Teensy, typically one provided by a BT adaptor
operating in 'pass-through' mode. The serial port COMPORT number is passed into this app
as an argument.
- Sends whatever command is required to put the existing Teensy firmware into 'update' mode
- Using the path of the updating program (passed in as an argument), locates the .HEX file
associated with the project, and sends it's contents to the Teensy, one line at a time, counting
lines and confirming checksums line-by-line
- Compares the number of lines sent to the Teensy with the number of lines received by the Teensy,
and if there is a match, allows the Teensy update process to complete; otherwise aborts
*/
namespace TeensyFlash
{
class Program
{
const string startCmdStr = "U"; //used in sketch's 'GetUserInput()' to start upload sequence
static string rcvStr = string.Empty;
private static System.Timers.Timer aTimer;
private static bool bTimedOut;
static void Main(string[] args)
{
//Extract the build path and selected COMPORT number from the arguments to the call to Main()
Console.WriteLine("Teensy Flash Console");
Console.WriteLine("Number of arguments in args = {0}\n", args.Length);
int argindex = 0;
string comPortStr = string.Empty;
foreach (var item in args)
{
Console.WriteLine(item);
if (item.Contains("COM"))
{
comPortStr = args[argindex];
}
argindex++;
}
string build_path = args[0];
string projectName = args[args.Length - 1];
projectName = projectName.Substring(0, projectName.Length - 4); //remove extension
build_path = build_path.Replace("\"", string.Empty).Trim();
string hexfilename = build_path + "\\" + projectName + ".hex";
Console.WriteLine("path = {0}", build_path);
Console.WriteLine("comport = {0}", comPortStr);
Console.WriteLine("build name = {0}", projectName);
Console.WriteLine("path to HEX file = {0}", hexfilename);
try
{
Stopwatch stopwatch = Stopwatch.StartNew();
string[] lines = System.IO.File.ReadAllLines(hexfilename);
foreach (string item in lines)
{
Console.WriteLine(item);
}
Console.WriteLine("this took " + stopwatch.ElapsedMilliseconds + " Msec");
}
catch (Exception)
{
throw;
}
Console.WriteLine("Opening Serial Port...");
try
{
SerialPort _serport = new SerialPort(comPortStr, 115200);
_serport.WriteTimeout = 1000;
_serport.WriteBufferSize = 20480;
_serport.Open();
_serport.DiscardOutBuffer();
_serport.DiscardInBuffer();
Thread.Sleep(100);
Console.WriteLine("Sending Trigger Character " + startCmdStr);
Console.WriteLine(startCmdStr);
_serport.Write(startCmdStr);
Console.WriteLine("Waiting for 'waiting' from Teensy...");
rcvStr = string.Empty;
aTimer = new System.Timers.Timer();
//aTimer.Interval = 5000;
aTimer.Interval = 25000;
aTimer.Elapsed += OnTimedEvent;
aTimer.Start();
while (!rcvStr.Contains("waiting") && !bTimedOut)
{
if (_serport.BytesToRead > 0)
{
rcvStr = _serport.ReadLine();
}
}
aTimer.Stop();
if (bTimedOut)
{
Console.WriteLine("Timed out waiting for 'waiting' response from Teensy");
}
else
{
//if we get to here, the Teensy is ready to receive HEX file contents
Console.WriteLine("Received " + rcvStr + " from Teensy");
Stopwatch stopwatch2 = Stopwatch.StartNew();
int numlines = 0;
string[] lines = System.IO.File.ReadAllLines(hexfilename);
foreach (string item in lines)
{
numlines++;
_serport.WriteLine(item);
}
Console.WriteLine("total lines = {0}, time = {1} mSec", numlines, stopwatch2.ElapsedMilliseconds);
//now we wait for Teensy to emit "hex file: xx lines xx bytes..." and then "enter xx to flash..."
aTimer.Start();
while (!rcvStr.Contains("hex file:") && !bTimedOut)
{
if (_serport.BytesToRead > 0)
{
rcvStr = _serport.ReadLine();
}
}
aTimer.Stop();
aTimer.Dispose();
if (bTimedOut)
{
Console.WriteLine("Timed out waiting for 'hex file' response from Teensy");
}
else
{
//extract number of lines from Teensy string, and compare with numlines.
//If they match, then send the number back to Teensy to complete the update.
//Otherwise, send '0' to abort
int colonIdx = rcvStr.IndexOf(':');
int lineIdx = rcvStr.IndexOf("lines");
string compareStr = rcvStr.Substring(colonIdx + 1, lineIdx - colonIdx - 1);
compareStr = compareStr.Trim();
int numTeensyLines = Convert.ToInt16(compareStr);
Console.WriteLine("sent {0} teensy replied {1}", numlines, numTeensyLines);
if (numTeensyLines == numlines)
{
Console.WriteLine("numlines {0} matches numTeensyLines {1} - send confirmation",
numlines, numTeensyLines);
_serport.WriteLine(compareStr);
}
}
}
}
catch (Exception)
{
throw;
}
try
{
}
catch (Exception)
{
throw;
}
}
static string chksum(string input)
{
int TwosComplement(string s)
{
if (s.Length % 2 != 0)
throw new FormatException(nameof(input));
var checksum = 0;
for (var i = 0; i < s.Length; i += 2)
{
var value = int.Parse(s.Substring(i, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
checksum = (checksum + value) & 0xFF;
}
return 256 - checksum & 0xFF;
}
//return string.Concat(":", input, " ", TwosComplement(input).ToString("X2"));
return TwosComplement(input).ToString("X2");
}
private static void SetTimer()
{
// Create a timer with a two second interval.
aTimer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
//aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
e.SignalTime);
bTimedOut = true;
}
}
}
The code that actually does the file transfer is:
Stopwatch stopwatch2 = Stopwatch.StartNew();
int numlines = 0;
string[] lines = System.IO.File.ReadAllLines(hexfilename);
foreach (string item in lines)
{
numlines++;
_serport.WriteLine(item);
}
Console.WriteLine("total lines = {0}, time = {1} mSec", numlines, stopwatch2.ElapsedMilliseconds);
When the '_serport.WriteLine(item);' line is commented out, the reported elapsed time is 0 mSec, as expected - so the 'ReadAllLines()' step isn't the problem.
Anyone have an idea why the 'WriteLine(item)' processing is so slow?
It depends on the structure of the method itself with the device, but I found on the same site an inquiry and means for it that help you
stackoverflow: console writeline slow

An alternative class for Tracert with DNS feature

I noticed, using Tracert on Windows, that if there is no data for DNS info, there is a delay too long to be acceptable - more or less 5 seconds. For this reason, I coded my own Tracert class with a latency parameter, waiting for an answer. All is done using a Task method. However, if I code for a few years, now I am trying to elaborate my code cleanly and efficiently. Please, can you tell me what I should change? Maybe you see some mistakes or non-senses. Thank you for your help ++
enter image description here
class TraceRoute
{
public void TraceRouteX(string ipAddressOrHostName, int hops = 30, int latency = 1000, bool dns = false)
{ // this way we can check if IP or HostName are valid
try
{ // a tip to get only IPv4
IPAddress ipAddress = Dns.GetHostAddresses(ipAddressOrHostName).First(address => address.AddressFamily == AddressFamily.InterNetwork);
using (Ping pingSender = new Ping())
{
PingOptions pingOptions = new PingOptions();
Stopwatch stopWatch = new Stopwatch();
byte[] bytes = new byte[32]; // 32 bits as packet
string hostName; // for DNS
PingReply pingReply;
pingOptions.DontFragment = true;
pingOptions.Ttl = 1;
int maxHops = hops;
// just a first message on screen before TraceRoute
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(string.Format(" TraceRoute to {0} with a maximum of {1} hops, setting latency to {2} and DNS feature to {3}\n", ipAddress, maxHops, latency, dns));
Console.ResetColor();
for (int i = 1; i < maxHops + 1; i++)
{ // for latence
stopWatch.Reset();
stopWatch.Start(); // ping options allows us to set TTL
pingReply = pingSender.Send(ipAddress, latency, new byte[32], pingOptions);
stopWatch.Stop();
if (dns)
{ // DNS resolving using a timer
Task<string> task = Task<string>.Factory.StartNew(() =>
{
var t = Dns.GetHostEntry(pingReply.Address).HostName;
return t.ToString(); // well well ?
});
// waiting an answer
bool success = task.Wait(latency);
if (success)
hostName = task.Result;
else
hostName = "TimeOut (no DNS info)";
}
else
hostName = "";
// display string with all informations - easy reading
if (i % 2 == 0)
Console.ForegroundColor = ConsoleColor.DarkYellow;
else
Console.ForegroundColor = ConsoleColor.Cyan;
// display final output
Console.WriteLine(string.Format(" h{0}\t{1} ms\t{2}\t\t{3}", i, stopWatch.ElapsedMilliseconds, pingReply.Address, hostName));
Console.ResetColor();
// status
if (pingReply.Status == IPStatus.Success)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("\n The IP target " + pingReply.Address + " has been reached");
Console.ResetColor();
break;
}
// increment TTL to get the next node
pingOptions.Ttl++;
}
}
}
catch
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(" ERROR: You Have Some TIMEOUT Issue Or An Invalid IP/Host");
Console.ResetColor();
}
}
}

I want to reply an sms with DHT11 values

#include<SoftwareSerial.h>
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
SoftwareSerial mySerial(10, 11);
int index = 0;
float h;
float temp;
char incomingByte;
String incomingData;
bool atCommand = true;
String message = "";
String number = "";
void setup()
{
Serial.begin(9600);
mySerial.begin(9600);
dht.begin();
while (!mySerial.available()) {
mySerial.println("AT");
delay(1000);
Serial.println("connecting....");
}
mySerial.println("AT+CMGF=1"); //Set SMS Text Mode
delay(1000);
mySerial.println("AT+CNMI=1,2,0,0,0"); //procedure, how to receive messages from the network
delay(1000);
//mySerial.println("AT+CMGL=\"REC UNREAD\""); // Read unread messages
mySerial.println("AT+CBAND=DCS_MODE");
Serial.println("Ready to receive Commands..");
}
void loop()
{
if (mySerial.available()) {
delay(100);
// Serial buffer
while (mySerial.available()) {
incomingByte = mySerial.read();
incomingData += incomingByte;
}
delay(10);
if (atCommand == false) {
receivedMessage(incomingData);
}
else {
atCommand = false;
}
//delete messages to save memory
if (incomingData.indexOf("OK") == -1) {
mySerial.println("AT+CMGDA=\"DEL ALL\"");
delay(1000);
atCommand = true;
}
incomingData = "";
}
if (message.indexOf("SEND") > -1) { //
SendTextMessage();
Serial.println("send");
}
}
void SendTextMessage()
{
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float temp = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
mySerial.println("AT+CMGF=1"); //To send SMS in Text Mode
delay(1000);
mySerial.println("AT+CMGS=" + number); // change to the phone number you using
delay(2000);
mySerial.print("Humidity: ");
mySerial.print(h);
mySerial.print(" % ");
mySerial.print("Temperature: ");
mySerial.print(temp);
mySerial.println(" *C ");
delay(200);
mySerial.println((char)26);//the stopping character
delay(1000);
}
void receivedMessage(String inputString) {
//Get The number of the sender
index = inputString.indexOf('"') + 1;
inputString = inputString.substring(index);
index = inputString.indexOf('"');
number = inputString.substring(0, index);
Serial.println("Number: " + number);
//Get The Message of the sender
index = inputString.indexOf("\n") + 1;
message = inputString.substring(index);
message.trim();
Serial.println("Message: " + message);
message.toUpperCase(); // uppercase the message received
Serial.println("receive");
delay(50);
}
This is my code and lets say i send an sms saying SEND from my number 1234 the code detects the number and when send the info to my number using this line
mySerial.println("AT+CMGS=" + number);
i get this in the serial monitor
connecting....
Ready to receive Commands..
Number:
OK
Message: OK
receive
Number: +1234
Message: SEND
receive
send
send
Number: AT+CMGF=1
OK
AT+CMGS=+1234
ERROR
Humidity: 64.00
Message: OK
AT+CMGS=+1234
ERROR
Humidity: 64.00
receive
and no message is there but if i change this code to mySerial.println("AT+CMGS=\"+1234\"\r");
it works but i dont want it to be a fixed number i want to reply to whatever number it receives
Thanks
The fixed/working code is: AT+CMGS="+1234"\r (with quotation marks before and after the number and a carriage return \r ), where the code in the sketch is AT+CMGS=+1234 (without quotation marks and no carriage return).
Try:
mySerial.println("AT+CMGS=\"" + number + "\"\r");

How do I break out of this particular while loop?

I have a while loop that begins when I press a button. I'm using it to maintain communication with a service on another computer. The problem is that when I get the "Completed" message back from the other computer I need it to break out of the while loop and stop listening till the button is pressed again. Nothing I do seems to break it out of the loop.
Please note the entire process is executed in its own thread.
I tried putting break; just before the end of the first case in the switch, no such luck and I'm not sure if it's because it's a switch statement that expects a break; between cases or what the reason is. I also tried putting return; in there but it still won't break out. I end up having to close the application and restart it to use the button again.
TcpClient client = new TcpClient(serverIP, 11000);
NetworkStream stream = client.GetStream();
Byte[] bytes = new Byte[256];
String data = null;
int i;
stream.Write(copy, 0, copy.Length);
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
//MessageBox.Show(data);
switch (data)
{
case "Completed":
this.Invoke((MethodInvoker)delegate
{
progressBar1.Value = 0;
progressBar1.Visible = false;
progressBar1.Update();
if (prod)
{
sqlLink.setProdFile(imageName, destFileName);
} else
{
sqlLink.setTestFile(imageName, destFileName);
if (sqlLink.getTestVM(imageName) != "")
{
if (message.Text("Test VM", "Power on specified Virtual Machine in private mode?", MessageBoxButtons.OKCancel) == DialogResult.OK)
{
PS ps = new PS();
ps.powerOnVM(sqlLink.getTestVM(imageName));
}
}
}
//Tried putting break; here.
});
break;
case "FIU":
{
progressBar1.Value = 0;
progressBar1.Visible = false;
progressBar1.Update();
message.Text("Error", "The image is in use. Try shutting down machines or unassigning devices.", MessageBoxButtons.OK);
}
break;
case "DSF":
{
progressBar1.Value = 0;
progressBar1.Visible = false;
progressBar1.Update();
message.Text("Error", "Drive space is full on production volume. Try deleting some older images.", MessageBoxButtons.OK);
}
break;
default:
this.Invoke((MethodInvoker)delegate
{
progressBar1.Value = Int16.Parse(data);
progressBar1.Update();
});
break;
}
}
stream.Close(); //This never happens.
client.Close();
}
catch (Exception ex)
{
message.Text("Error", "Copy Method Error: " + ex.Message, MessageBoxButtons.OK);
}
Define a boolean variable that will hold the fact that you received the "Completed" message.
When you'll be entering the next iteration, if this value is true, then you break and you'll be getting out of your loop.
Example :
// Abbreviated
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
bool breakTheWhile = false;
switch (data)
{
case "Completed":
// Abbreviated
breakTheWhile = true;
break;
case "FIU":
// Abbreviated
break;
case "DSF":
// Abbreviated
break;
default:
// Abbreviated
break;
}
if (breakTheWhile)
break;
}

Categories