Basically, I am calibrating and applying offsets within unity. But the range of rotation isn't accurate and I'm wondering if its because of the wrong sensitivity application. I wanted help figuring out a way to stabilize the rotation as well as increase the range of rotation as it goes only form 0-90 and it shakes a lot.
Unity Code:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
public class MPU6050_3 : MonoBehaviour
{
public GameObject target;
SerialPort stream = new SerialPort("COM3", 115200);
string[] accgyValues = new string[10];
int buffersize = 1000; //Amount of readings used to average, make it higher to get more precision but sketch will be slower (default:1000)
int acel_deadzone = 2; //Acelerometer error allowed, make it lower to get more precision, but sketch may not converge (default:8)
int giro_deadzone = 1; //Giro error allowed, make it lower to get more precision, but sketch may not converge (default:1)
float ax, ay, az, gx, gy, gz, gx_f, gy_f, gz_f;
float mean_ax, mean_ay, mean_az, mean_gx, mean_gy, mean_gz, state = 0;
float ax_offset = 0, ay_offset = 0, az_offset = 0, gx_offset = 0, gy_offset = 0, gz_offset = 0;
bool cal;
public float factor = 1;
public bool enableRotation;
public bool enableTranslation;
//float acc_normalizer_factor = 0.00025f;
float gyro_normalizer_factor = 1.0f/65.5f;
void Awake()
{
stream.Open();
//stream.ReadTimeout=50;
}
void Update()
{
if (state == 0)
{
accel();
Debug.Log("\nReading sensors for first time...");
state++;
Debug.Log("State is:"+state);
}
else if (state == 1)
{
Debug.Log("\nCalculating offsets...");
calibration();
state++;
Debug.Log("State is:" + state);
}
else if (state == 2)
{
accel();
Debug.Log("SensorW/Offset:" + mean_ax + ":" + mean_ay + ":" + mean_az + ":" + mean_gx + ":" + mean_gy + ":" + mean_gz);
Debug.Log("Offset:" + ax_offset + ":" + ay_offset + ":" + az_offset + ":" + gx_offset + ":" + gy_offset + ":" + gz_offset);
state++;
Debug.Log("State is:" + state);
}
else if (state == 3)
{
getaccgy();
//if (enableTranslation) target.transform.position = new Vector3(ax+ax_offset, az-az_offset, ay-ay_offset);
gx_f = (gx + gx_offset) * gyro_normalizer_factor;
gy_f = (gy + gy_offset) * gyro_normalizer_factor;
gz_f = -(gz + gz_offset) * gyro_normalizer_factor ;
if (enableRotation) target.transform.rotation = Quaternion.Euler(gx_f * factor, gz_f * factor, gy_f * factor);
Debug.Log("ValueRot "+ gx_f +" " + gy_f + " " + gz_f);
Debug.Log("State is:" + state);
}
}
public void getaccgy()
{
stream.Write("r");
Debug.Log("In accel");
string value;
accgyValues = new string[10];
value = stream.ReadLine();
accgyValues = value.Split(",");
ax = int.Parse(accgyValues[0]); //* acc_normalizer_factor;
ay = int.Parse(accgyValues[1]); //* acc_normalizer_factor;
az = int.Parse(accgyValues[2]); //* acc_normalizer_factor;
gx = int.Parse(accgyValues[3]); //* gyro_normalizer_factor;
gy = int.Parse(accgyValues[4]); //* gyro_normalizer_factor;
gz = int.Parse(accgyValues[5]); //* gyro_normalizer_factor;
Debug.Log("GetACCGY");
Debug.Log("SensorW/Offset:" + ax + ":" + ay + ":" + az + ":" + gx + ":" + gy + ":" + gz);
}
void accel()
{
float i = 0f, buff_ax = 0f, buff_ay = 0f, buff_az = 0f, buff_gx = 0f, buff_gy = 0f, buff_gz = 0f;
while (i < 1101)
{
getaccgy();
if (cal)
{
ax = ax + ax_offset;
ay = ay + ay_offset;
az = az + az_offset;
gx = gx + gx_offset;
gy = gy + gy_offset;
gz = gz + gz_offset;
}
if (i > 99 && i < (buffersize + 100))
{ //First 100 measures are discarded
buff_ax += ax;
buff_ay += ay;
buff_az += az;
buff_gx += gx;
buff_gy += gy;
buff_gz += gz;
}
if (i == (buffersize + 100))
{
mean_ax = buff_ax / buffersize;
mean_ay = buff_ay / buffersize;
mean_az = buff_az / buffersize;
mean_gx = buff_gx / buffersize;
mean_gy = buff_gy / buffersize;
mean_gz = buff_gz / buffersize;
Debug.Log("Mean:" + mean_ax + ":" + mean_ay + ":" + mean_az + ":" + mean_gx + ":" + mean_gy + ":" + mean_gz);
}
i++;
Debug.Log("Mean Sensor");
Debug.Log("Buffer Size is" + buffersize + "i mean" + i);
Debug.Log("SensorW/Offset:" + ax + ":" + ay + ":" + az + ":" + gx + ":" + gz);
}
}
void calibration()
{
cal = true;
Debug.Log("Callibration Entered");
ax_offset = -mean_ax / 8;
ay_offset = -mean_ay / 8;
az_offset = (16384 - mean_az) / 8;
gx_offset = -mean_gx / 4;
gy_offset = -mean_gy / 4;
gz_offset = -mean_gz / 4;
int ready = 0;
while (ready < 7)
{
//accelgyro.setXAccelOffset(ax_offset);
//accelgyro.setYAccelOffset(ay_offset);
//accelgyro.setZAccelOffset(az_offset);
//accelgyro.setXGyroOffset(gx_offset);
//accelgyro.setYGyroOffset(gy_offset);
//accelgyro.setZGyroOffset(gz_offset);
accel();
Debug.Log("..." + ready);
if (Math.Abs(mean_ax) <= acel_deadzone) ready++;
else ax_offset = ax_offset - mean_ax / acel_deadzone;
if (Math.Abs(mean_ay) <= acel_deadzone) ready++;
else ay_offset = ay_offset - mean_ay / acel_deadzone;
if (Math.Abs(16384 - mean_az) <= acel_deadzone) ready++;
else az_offset = az_offset + (16384 - mean_az) / acel_deadzone;
if (Math.Abs(mean_gx) <= giro_deadzone) ready++;
else gx_offset = gx_offset - mean_gx / (giro_deadzone + 1);
if (Math.Abs(mean_gy) <= giro_deadzone) ready++;
else gy_offset = gy_offset - mean_gy / (giro_deadzone + 1);
if (Math.Abs(mean_gz) <= giro_deadzone) ready++;
else gz_offset = gz_offset - mean_gz / (giro_deadzone + 1);
if (ready == 6) break;
}
}
}
Arduino Code:
Just a simple code to get the raw values:
// I2Cdev and MPU6050 must be installed as libraries
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"
/////////////////////////////////// CONFIGURATION /////////////////////////////
//Change this 3 variables if you want to fine tune the skecth to your needs.
int buffersize=1000; //Amount of readings used to average, make it higher to get more precision but sketch will be slower (default:1000)
int acel_deadzone=8; //Acelerometer error allowed, make it lower to get more precision, but sketch may not converge (default:8)
int giro_deadzone=1; //Giro error allowed, make it lower to get more precision, but sketch may not converge (default:1)
// default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
//MPU6050 accelgyro;
MPU6050 accelgyro(0x68); // <-- use for AD0 high
int16_t ax, ay, az,gx, gy, gz;
int mean_ax,mean_ay,mean_az,mean_gx,mean_gy,mean_gz,state=0;
int ax_offset,ay_offset,az_offset,gx_offset,gy_offset,gz_offset;
/////////////////////////////////// SETUP ////////////////////////////////////
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
Wire.begin();
// COMMENT NEXT LINE IF YOU ARE USING ARDUINO DUE
TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz). Leonardo measured 250kHz.
// initialize serial communication
Serial.begin(115200);
// initialize device
accelgyro.initialize();
//wait for ready
//while (Serial.available() && Serial.read()); // empty buffer
//while (!Serial.available()){
//Serial.println(F("Send any character to start sketch.\n"));
//delay(1500);
//}
//while (Serial.available() && Serial.read()); // empty buffer again
}
// start message
//Serial.println("\nMPU6050 Calibration Sketch");
//delay(2000);
//Serial.println("\nYour MPU6050 should be placed in horizontal position, with package letters facing up. \nDon't touch it until you see a finish message.\n");
//delay(3000);
// verify connection
//Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
//delay(1000);
// reset offsets
//accelgyro.setXAccelOffset(0);
//accelgyro.setYAccelOffset(0);
//accelgyro.setZAccelOffset(0);
//accelgyro.setXGyroOffset(0);
//accelgyro.setYGyroOffset(0);
//accelgyro.setZGyroOffset(0);
void loop() {
if(Serial.available() > 0)
{
char ltr = Serial.read();
if(ltr == 'r')
{
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
Serial.print(ax);
Serial.print(",");
Serial.print(ay);
Serial.print(",");
Serial.print(az);
Serial.print(",");
Serial.print(gx);
Serial.print(",");
Serial.print(gy);
Serial.print(",");
Serial.println(gz);
Serial.flush();
}
}
}
Related
I've built a C# application to interact with a Control System at work. It calculates some values and/or pulls them from a spreadsheet and then writes them to an OPC server using EasyOPCClient. When I run this application, it will run for 3-5 minutes the first time, close, and reopen, then run 30 seconds to 2 minutes from that point on. Each time it closes and restarts with no errors printed to the console (at least that I can see before it closes), and I don't see anything in the event logs that would make it close. Does anyone see anything I'm doing in the program that would cause that? This is my first attempt at multi-threading, so it wouldn't surprise me if it were something with that.
using System;
using System.IO;
using System.Threading;
using OpcLabs.EasyOpc.DataAccess;
using Excel = Microsoft.Office.Interop.Excel;
/// <summary>
/// OPC Simulator:
/// Used to assist in training operators on how to use Honeywell Experion System
/// Simulates PID and DEVCTL inputs and outputs; uses historical data from ParcView to simulate DACA blocks
///
/// Date: 07/14/2022
/// Authours:
/// </summary>
namespace OPCTest
{
public class Program
{
public static double[] genFunction(int number_of_samples, float amplitude, float frequency_in_hz)
{
/*
* Function: Generates an array of points sampled from a noisy sine wave function.
*
* IN: number_of_samples - The number of samples to generate
* amplitude - Multiplier to scale the function
* frequency_in_hz - Frequency of the generated signal
*
* OUT: An array of integers sampled from the generated sine wave.
*/
Random rand = new Random();
// Initialize any needed variables
double[] points = new double[number_of_samples];
float time;
int samples;
// Generates a noisy signal
for(samples = 0; samples < number_of_samples; samples++)
{
time = samples / (frequency_in_hz);
points[samples] = amplitude * (Math.Sin(2.0f * Math.PI * frequency_in_hz * time / 5.0f + rand.Next(0, 100))
+ 1/5 * Math.Sin(2.0f * Math.PI * frequency_in_hz * time + rand.Next(0, 100))
+ 3 * (Math.Sin(2.0f * Math.PI * frequency_in_hz * time / 100.0f + rand.Next(0, 100))));
}
return points;
}
public static void DACA(EasyDAClient client)
{
/*
* Function: Simulates DACA block I/Os using a function generator
*
* IN: None
*
* OUT: None
*
*/
//var client = new EasyDAClient();
string textFile = #"C:\Temp\DACAs.txt"; // Path to file with CMs containing DACAs in it. CM name only
float pveulo, pveuhi, pvloalm, pvhialm, pvllalm, pvhhalm; // Initialize all of the useful PV alarms and variables
float pv, pvlo, pvhi; // PVs that will be used in calculations
float shift; // Initialize the variable that will vertically shift the signal to the correct magnitude
float amplitude; // Initialize the variable that will determine the amplitude of each PV signal
double[] signal; // Initialize an array of points that will be used to store a generated signal
// Read a text file line by line.
string[] lines = File.ReadAllLines(textFile);
while (true)
{
if (File.Exists(textFile))
{
// Iterate through DACAs in text file
foreach (string line in lines)
{
try
{
// Store the necessary variables
pvhi = pveuhi = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEUHI").ToString());
pvlo = pveulo = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEULO").ToString());
if (float.TryParse(client.ReadItem("", "HWHsc.OPCServer", line + ".DACA.PVHHALM.TP").ToString().Split(' ')[0], out pvhhalm))
{
// Console.WriteLine("PVHIHI: " + pvhhalm);
pvhi = pvhhalm;
}
if (float.TryParse(client.ReadItem("", "HWHsc.OPCServer", line + ".DACA.PVHIALM.TP").ToString().Split(' ')[0], out pvhialm))
{
// Console.WriteLine("PVHI: " + pvhialm);
pvhi = pvhialm;
}
if (float.TryParse(client.ReadItem("", "HWHsc.OPCServer", line + ".DACA.PVLLALM.TP").ToString().Split(' ')[0], out pvllalm))
{
// Console.WriteLine("PVLOLO: " + pvllalm);
pvlo = pvllalm;
}
if (float.TryParse(client.ReadItem("", "HWHsc.OPCServer", line + ".DACA.PVLOALM.TP").ToString().Split(' ')[0], out pvloalm))
{
// Console.WriteLine("PVLO: " + pvloalm);
pvlo = pvloalm;
}
// Console.WriteLine("PVHI: " + pvhi + " PVLO: " + pvlo);
amplitude = ((pvhi - pvlo) / 2.0f) * 0.0375f;
shift = ((pvhi - pvlo) * 0.8f) + pvlo; // Shift the signal up to oscillate between the bounds of the PV
// Generate the signal
signal = genFunction(10, amplitude, 0.003f);
foreach (float sig in signal)
{
pv = sig + shift;
client.WriteItemValue("", "HWHsc.OPCServer", line + ".DACA.PV", pv);
// Console.WriteLine(line + ": " + pv);
}
}
catch(Exception e)
{
// Note the failures
Console.WriteLine("DACA Failed at: " + line + "\n\t" + e + "\n");
}
}
System.Threading.Thread.Sleep(1000);
}
}
}
public static void DEVCTLA(EasyDAClient client)
{
/*
* Function: Simulates DEVCTLA block I/Os
*
* IN: client - OPC Client that will be used to read and write to the Experion server
*
* OUT: None
*/
string textFile = #"C:\Temp\DEVCTLAs.txt";
string gop, gpv;
// Read a text file line by line.
string[] tags = File.ReadAllLines(textFile);
while (true)
{
foreach (string tagName in tags)
{
try
{
gop = client.ReadItemValue("", "HWHsc.OPCServer2", tagName + ".DEVCTLA.GOP").ToString();
gpv = client.ReadItemValue("", "HWHsc.OPCServer2", tagName + ".DEVCTLA.GPV").ToString();
if (gpv != gop) client.WriteItemValue("", "HWHsc.OPCServer2", tagName + ".DEVCTLA.GPV", gop);
}
catch(Exception e)
{
Console.WriteLine("DEVCTLA Failed at: " + tagName + "\n\t" + e + "\n");
}
}
System.Threading.Thread.Sleep(1000);
}
}
public static void PID(EasyDAClient client)
{
/*
* Function: Simulates PID block I/Os
*
* IN: client - OPC Client that will be used to read and write to the Experion server
*
* OUT: None
*/
string textFile = #"C:\Temp\PIDs.txt"; // Path to file with CMs containing PIDs in it. CM name only - I plan to make this browsable by the user
double OP = 0; // Place to store OP of PID
double pveulo = 0; // Place to store PVEULO from DACA
double pveuhi = 0; // Place to store PVEUHI from DACA
double PV = 0; // Place to store calculated PV to write to DACA
double ctlactn = 1; // Place to store Control Action - 0 = Direct, 1 = Reverse
// Read a text file line by line.
string[] lines = File.ReadAllLines(textFile);
foreach (string line in lines)
{
try
{
client.WriteItemValue("", "HWHsc.OPCServer", line + "PIDA.MODE", "AUTO"); // Put PID Loops in Automatic
}
catch { }
}
while (true)
{
if (File.Exists(textFile))
{
// Iterate through PIDs in text file
foreach (string line in lines)
{
try
{
// Store the PVEULO
pveulo = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEULO").ToString());
// Store the PVEUHI
pveuhi = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEUHI").ToString());
// Store the OP
OP = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".PIDA.OP").ToString());
// Store the PV
try
{
PV = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".PIDA.PV").ToString());
}
catch
{
PV = 0;
}
// Store the Control Action
try
{
ctlactn = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".PIDA.CTLACTN").ToString());
}
catch (Exception e)
{
//ctlactn2 = client.ReadItemValue("", "HWHsc.OPCServer", line + "PIDA.CTLACTN").ToString();
//ctlactn2 = e.ToString();
}
// If PV is 0, write the halfway point to it so the PID doesn't start in a wound up position
if (PV == 0)
{
// Write the halfway point of the pv range to the PV
client.WriteItemValue("", "HWHsc.OPCServer", line + ".DACA.PV", (pveuhi - pveulo) / 2);
}
if (ctlactn == 1)
{
// Calculate the PV based off the OP * PV Range + some noise
PV = (OP * 0.01 * (pveuhi - pveulo) + pveulo) + 0.008 * OP;
}
else
{
// Calculate the PV based off the OP * PV Range + some noise
PV = ((106.9 - OP) * 0.01 * (pveuhi - pveulo) + pveulo) - 0.008 * (106.9 - OP);
}
// Write the calculated PV to the DACA
client.WriteItemValue("", "HWHsc.OPCServer", line + ".DACA.PV", PV);
}
catch(Exception e)
{
// Note the failures
Console.WriteLine("PID Failed at: " + line + "\n\t" + e + "\n");
Thread.Sleep(300000);
}
}
System.Threading.Thread.Sleep(1000);
}
}
}
public static void PView(EasyDAClient client)
{
/*
* Function: Simulates DACA block I/Os using historical ParcView data
*
* IN: client - OPC Client that will be used to read and write to the Experion server
* xLWB - The excel workbook containing the ParcView data
* OUT: None
*/
// Connect to the Excel spreadsheet
Excel.Application xLApp = new Excel.Application();
Excel.Workbook xLWB = xLApp.Workbooks.Open(#"C:\Temp\ParcView_Data_Copy_2.xlsx");
Excel.Worksheet rawData = xLWB.Sheets[1];
Excel.Worksheet locData = xLWB.Sheets[2];
Excel.Range rawDataRange = rawData.UsedRange;
Excel.Range locDataRange = locData.UsedRange;
// Determine the size of the spreadshees
int rawDataRow = rawDataRange.Rows.Count;
int rawDataCol = rawDataRange.Columns.Count;
int locDataRow = locDataRange.Rows.Count;
string tagName;
float[] tagValues = new float[locDataRow];
do
{
// Loop through each row of data
for (int i = 1; i <= rawDataRow; i++)
{
// Console.WriteLine((rawDataRow - i) + " Remaining");
// Get data for tag
for (int j = 1; j <= locDataRow; j++)
{
tagName = locDataRange.Cells[j, 1].Value2.ToString();
try
{
if (rawDataRange.Cells[i, j] != null && rawDataRange.Cells[i, j].Value2 != null)
tagValues[j - 1] = float.Parse(rawDataRange.Cells[i, j].Value2.ToString());
client.WriteItemValue("", "HWHsc.OPCServer", tagName + ".DACA.PV", tagValues[j - 1]);
}
catch (Exception e)
{
Console.WriteLine("PVIEW Failed at: " + tagName + "\n\t" + e + "\n");
Thread.Sleep(300000);
}
}
Thread.Sleep(2000);
}
} while (true);
}
static void Main(string[] args)
{
try
{
// Initialize OPC Client
EasyDAClient client = new EasyDAClient();
EasyDAClient client2 = new EasyDAClient();
// Initialize threads using Threads class
Thread PViewThread = new Thread(() => PView(client));
Thread PIDThread = new Thread(() => PID(client2));
//Thread DACAThread = new Thread(() => DACA(client));
//Thread DEVCTLAThread = new Thread(() => DEVCTLA(client));
// Start the threads
PViewThread.Start();
PIDThread.Start();
//DACAThread.Start();
//DEVCTLAThread.Start();
}
catch (Exception e)
{
Console.WriteLine("MAIN: \n\t" + e);
Thread.Sleep(300000);
}
}
}
}
A C# program can launch another instance of itself with Process.Start. This code does not do that. It can be restarted by a task scheduler or if it is installed as a Windows service or by another application.
But I see that you have several Thread.Sleep in there. Those are probably responsible for the observed behavior. So, the program is not closing and restarting automatically. It is simply sleeping from time to time.
Especially when an exception occurs Thread.Sleep(300000); is called, making the program sleep for 5 minutes. If the exceptions occur randomly, this would explain it happening at random intervals.
E.g. float.Parse throws an exception when the string is not a valid float. Consider using TryParse instead. Example
string s = client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEUHI").ToString();
if (float.TryParse(s, out float pvhi)) {
pveuhi = pvhi;
...
} else {
Console.WriteLine($"\"{s}\" is not a valid float in line {line}");
}
I am developing a system that makes mp4 stream with c # asp.net. Chromium-based browsers can stream videos without error, but firefox and internet explorer can not stream videos. I response http request with byte array (partial 206). here is the code Where does the problem come from
thanks.
/// source code
/// Base on
/// http://videostreamer.codeplex.com/
int KBps;
switch (res)
{
case NResolution.HD1080p:
KBps = 1250000;
break;
case NResolution.HD720p:
KBps = 750000; break;
case NResolution.HD480p:
KBps = 750000; break;
case NResolution.HD320p:
KBps = 400000; break;
case NResolution.HD144p:
KBps = 200000; break;
default:
KBps = 200000; break;
}
using (var reader = new FileStream(fullpath,FileMode.Open,FileAccess.Read,FileShare.Read,KBps,FileOptions.SequentialScan))
{
var size = reader.Length;
var end = size - 1;
var start = 0;
Int64 anotherStart = 0;
Int64 anotherEnd = 0;
resp.AddHeader("Accept-Ranges","0-"+size.ToString());
resp.StatusCode = 206;
var rng = req.Headers.Get("Range");
if (!string.IsNullOrEmpty(rng))
{
if (rng.IndexOf(",") > -1)
{
resp.AddHeader("Content-Range","bytes " + start + "-" + end +"/" + size);
throw new HttpException(416,"Error...");
}
if (rng.StartsWith("-"))
{
anotherStart = Int64.Parse(rng.Substring(1));
}
else
{
anotherStart = Int64.Parse(rng.Split('=')[1].Split('-')[0]);
}
if (anotherStart + KBps <= end)
{
anotherEnd = anotherStart + KBps;
}
else
{
anotherEnd = end;
}
var length = anotherEnd - anotherStart + 1 ;
resp.AddHeader("Content-Range","bytes " + anotherStart + "-" +anotherEnd + "/" + size);
resp.AddHeader("Content-Length",length.ToString());
var buf = new byte[length];
reader.Seek(anotherStart, SeekOrigin.Begin);
reader.Read(buf, 0, buf.Length);
resp.OutputStream.Write(buf,0,buf.Length);
resp.Flush();
resp.End();
}
resp.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
resp.AddHeader("Content-Length", "0");
}
How are you setting the request header 'Range'. Please check that.
I am trying to make some buttons which change variables, so instead of writing new code every time I have to make a new button, I made a function which could do it for me.
The method "void buttons" has 4 arguments, but the "numberOF" argument does not work. When I clicked on the button, it was supposed to change arguement "numberOf" and "price", but it will never change "numberOf" for some reason.
Hopefully there is someone here that can help me. I know there is a lot of stuff I didn't use. I did the buttons with a long code every time when I tried this the first time, so there is some extraneous code still needing to be cleaned out.
using UnityEngine;
using System.Collections;
public class Gui : MonoBehaviour
{
public int one;
//Money
public int money;
//Iventory
public int stone;
public int jord;
public int frø;
public int korn;
public int brød;
//Item price
public int stonePrice;
public int jordPrice;
public int frøPrice;
public int kornPrice;
public int brødPrice;
//Item inventory text and button text
private string moneyText;
private string stoneText;
private string jordText;
private string frøText;
private string kornText;
private string brødText;
private string stoneButton;
private string jordButton;
private string frøButton;
private string kornButton;
private string brødButton;
//Screen heith/width = 0
private int screenWidth;
private int screenHeight;
// Runs one time
void Start ()
{
//Set variables to screen heith/width to 0
screenWidth = Screen.width - Screen.width;
screenHeight = Screen.height - Screen.height;
//Money reset
money = 10000;
//inventory reset
stone = 0;
jord = 0;
frø = 0;
korn = 0;
brød = 0;
//item price reset
stonePrice = 1;
jordPrice = 3;
frøPrice = 5;
kornPrice = 7;
brødPrice = 9;
//Set item text
moneyText = "money: " + money + " kr.";
stoneText = " stone " + stone;
jordText = " jord " + jord;
frøText = " frø " + frø;
kornText = " korn " + korn;
brødText = " brød " + brød;
//set button text
stoneButton = "Stone " + stonePrice + " kr.";
jordButton = "Jord " + jordPrice + " kr.";
frøButton = "Frø " + frøPrice + " kr.";
kornButton = "Korn " + kornPrice + " kr.";
brødButton = "Brød " + brødPrice + " kr.";
}
void Update ()
{
stone = stone;
jord = jord;
frø = frø;
korn = korn;
brød = brød;
moneyText = moneyText;
stoneText = stoneText;
jordText = jordText;
frøText = frøText;
kornText = kornText;
brødText = brødText;
//Check item text changes
moneyText = "money: " + money + " kr.";
stoneText = " stone " + stone;
jordText = " jord " + jord;
frøText = " frø " + frø;
kornText = " korn " + korn;
brødText = " brød " + brød;
//Check button text changes
stoneButton = "Stone " +stonePrice + " kr.";
jordButton = "Jord " + jordPrice + " kr.";
frøButton = "Frø " + frøPrice + " kr.";
kornButton = "Korn " + kornPrice + " kr.";
brødButton = "Brød " + brødPrice + " kr.";
}
void OnGUI ()
{
buttons(150, stoneButton, stone, stonePrice);
if (GUI.Button (new Rect (Screen.width - 100, Screen.height - 20, 100, 20), "End Turn"))
{
newRound();
}
//Iventory
GUI.TextArea (new Rect (screenWidth + 1, screenHeight + 2, Screen.width, 20),moneyText + " Inventory: " + stoneText + jordText + frøText + kornText + brødText);
}
void make_buttons(int position_heigth, string buttonText, int numberOF, int price)
{
GUI.TextArea (new Rect (screenWidth + 2, screenHeight + position_heigth + 80, 80, 20), buttonText);
if (GUI.Button (new Rect (screenWidth + 80, screenHeight + position_heigth + 80, 40, 20), "Buy"))
{
if (money > price)
{
numberOF = 1 + numberOF;
money = money - price;
}
else if (money == price)
{
numberOF = 1 + numberOF;
money = money - price;
}
}
if (GUI.Button (new Rect (screenWidth + 120, screenHeight + position_heigth + 80, 40, 20), "Sell"))
{
if (numberOF > 0)
{
numberOF = numberOF - 1;
money = money + price;
}
}
}
void newRound ()
{
stonePrice = stonePrice * 2;
jordPrice = jordPrice * 2;
frøPrice = frøPrice * 2;
kornPrice = kornPrice * 2;
brødPrice = brødPrice * 2;
}
}
I believe you are saying that the function does not modify the value of "numberOf".
This is not strictly true, however what you are doing is modifying a now local value. The reason for this is you are passing in an int, which is not passed by reference but rather by value.
You could probably correct this by modifying numberOf to ref numberOf, but I would actually recommend just returning numberOf if possible. It's more straight forward and clearer to understand what happened.
I would also recommend better variable and method names for buttons as it's not at ALL clear what action buttons is supposed to perform.
For further information on using ref arguments in C# this article is quite good.
I have found plenty of information on how to look at physical drives but I need to monitor several mount points on my physical drives. I would prefer to do this through wmi but any .NET objects that could do it would be fine as well.
So I figured this one out finally. With WMI its a constant battle against poor documentation and just figuring out this stuff on your own.
RESOURCES
wbemtest for testing your queries
wbemtest reference
scriptomatic for generating wmi scipts in several languages
scriptomatic
The code:
using System;
using System.IO;
using System.Management;
using System.Diagnostics;
namespace Monitor
{
class Program
{
static void Main(string[] args)
{
double Free, Size, FreePercentage;
DateTime Now = DateTime.Now;
string scopeStr = string.Format(#"root\cimv2", "TestSqlServer");
ManagementScope scope = new ManagementScope(scopeStr);
scope.Connect();
string queryString = "SELECT * FROM Win32_Volume WHERE DriveLetter IS NULL";
SelectQuery query = new SelectQuery(queryString);
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
Console.WriteLine("Entering Volume loop: ");
foreach (ManagementObject disk in searcher.Get())
{
Console.WriteLine("foreach Volume: ");
//-------------------------------------------------------------------------
//Console.WriteLine("Free %" + double.Parse(disk["FreeSpace"].ToString()) / double.Parse(disk["Capacity"].ToString()) * 100);
FreePercentage = double.Parse(disk["FreeSpace"].ToString()) / double.Parse(disk["Capacity"].ToString()) * 100;
//-------------------------------------------------------------------------
string _MountPoint = disk["Name"].ToString();
//Console.WriteLine("Free: " + disk["FreeSpace"].ToString());
Free = Math.Round(Convert.ToDouble(disk["FreeSpace"]) / (1024 * 1024), 2);
Console.WriteLine("Free: " + Free + " MB");
//Console.WriteLine("Capacity: " + disk["Capacity"].ToString());
Size = Math.Round(Convert.ToDouble(disk["Capacity"]) / (1024 * 1024), 2);
Console.WriteLine("Size: " + Size + " MB");
if (_MountPoint[_MountPoint.Length - 1] == Path.DirectorySeparatorChar)
{
_MountPoint = _MountPoint.Remove(_MountPoint.Length - 1);
}
_MountPoint = _MountPoint.Replace("\\", "\\\\\\\\");
string _MountPointQueryString = "select * FROM Win32_MountPoint WHERE Directory=\"Win32_Directory.Name=\\\"" + _MountPoint + "\\\"\"";
SelectQuery _MountPointQuery = new SelectQuery(_MountPointQueryString);
using (
ManagementObjectSearcher mpsearcher =
new ManagementObjectSearcher(scope, _MountPointQuery))
{
Console.WriteLine("Entering directory Foreach loop: ");
foreach (ManagementObject mp in mpsearcher.Get())
{
Console.WriteLine("Foreach directory: ");
try
{
//Console.WriteLine("Volume: " + mp["Volume"].ToString());
Console.WriteLine("Directory: " + mp["Directory"].ToString());
string Volume = mp["Directory"].ToString().Replace("Win32_Directory.Name=", "");
if (FreePercentage <= 5.00)
{
throw new Exception("\nLabel: " + Volume + "\nSeverity: " + EventLogEntryType.Error + "\nTime: " + Now + "\nMessage: disk space threshhold: " + CalculateUsedSpace(Free, Size) + " % used (" + Free + "MB" + " free)");
}
}
catch (Exception ex)
{
EventLog.WriteEntry("DriveStats Warning", "Message: " + ex.Message, EventLogEntryType.Error);
}
}
}
}
}
}
static double CalculateUsedSpace(double f, double s)
{
double UsedPercentage;
if (s == 0)
{
return f;
}
else if (s >= 0 && f == 0)
{
UsedPercentage = 100.00;
return UsedPercentage;
}
else
{
double UsedSpace = s - f;
UsedPercentage = (UsedSpace / s) * 100;
UsedPercentage = Math.Round(UsedPercentage, 2);
//Console.WriteLine("Used Percentage: " + UsedPercentage);
return Math.Round(UsedPercentage, 2);
}
}
static double CalculateFreePercentage(double f, double s)
{
double FreePercentage;
if (f == 0)
{
FreePercentage = 0;
return FreePercentage;
}
else
{
FreePercentage = (f / s) * 100;
//Console.WriteLine("Free Percentage: " + FreePercentage);
return Math.Round(FreePercentage, 2);
}
}
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 1 year ago.
Improve this question
Is there any built in method in the .NET library that will return all of the MX records for a given domain? I see how you get CNAMES, but not MX records.
Update 2018/5/23:
Check out MichaC's answer for a newer library that has .NET standard support.
Original Answer:
The ARSoft.Tools.Net library by Alexander Reinert seems to do the job pretty well.
It's available from NuGet:
PM> Install-Package ARSoft.Tools.Net
Import the namespace:
using ARSoft.Tools.Net.Dns;
Then making a synchronous lookup is as simple as:
var resolver = new DnsStubResolver();
var records = resolver.Resolve<MxRecord>("gmail.com", RecordType.Mx);
foreach (var record in records) {
Console.WriteLine(record.ExchangeDomainName?.ToString());
}
Which gives us the output:
gmail-smtp-in.l.google.com.
alt1.gmail-smtp-in.l.google.com.
alt2.gmail-smtp-in.l.google.com.
alt3.gmail-smtp-in.l.google.com.
alt4.gmail-smtp-in.l.google.com.
Underneath the hood, it looks like the library constructs the UDP (or TCP) packets necessary to send to the resolver, like you might expect. The library even has logic (invoked with DnsClient.Default) to discover which DNS server to query.
Full documentation can be found here.
Just roled my own library because there was nothing for .net core / xplat support... https://github.com/MichaCo/DnsClient.NET
It works pretty great and gives you dig like log messages if you want.
Simple to use
var lookup = new LookupClient();
var result = await lookup.QueryAsync("google.com", QueryType.ANY);
and works with custom servers running on any ports, multiple servers, etc...
see also DnsClient Website for more details
I spent all day figuring out how to send/receive dns requests and came up with this. Its a complete generic handler. You just have to set the dns server and pass in 'd' eg. my.website.com?d=itmanx.com
<%# WebHandler Language="C#" Class="Handler" %>
using System;
using System.Web;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
public class Handler : IHttpHandler
{
string dns = "dc1"; //change to your dns
string qtype = "15"; //A=1 MX=15
string domain = "";
int[] resp;
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
try
{
if (context.Request["t"] != null) qtype = context.Request["t"];
if (context.Request["d"] != null) domain = context.Request["d"];
if (string.IsNullOrEmpty(domain)) throw new Exception("Add ?d=<domain name> to url or post data");
Do(context);
}
catch (Exception ex)
{
string msg = ex.Message;
if (msg == "1") msg = "Malformed packet";
else if (msg == "5") msg = "Refused";
else if (msg == "131") msg = "No such name";
context.Response.Write("Error: " + msg);
}
}
public void Do(HttpContext context)
{
UdpClient udpc = new UdpClient(dns, 53);
// SEND REQUEST--------------------
List<byte> list = new List<byte>();
list.AddRange(new byte[] { 88, 89, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 });
string[] tmp = domain.Split('.');
foreach (string s in tmp)
{
list.Add(Convert.ToByte(s.Length));
char[] chars = s.ToCharArray();
foreach (char c in chars)
list.Add(Convert.ToByte(Convert.ToInt32(c)));
}
list.AddRange(new byte[] { 0, 0, Convert.ToByte(qtype), 0, 1 });
byte[] req = new byte[list.Count];
for (int i = 0; i < list.Count; i++) { req[i] = list[i]; }
udpc.Send(req, req.Length);
// RECEIVE RESPONSE--------------
IPEndPoint ep = null;
byte[] recv = udpc.Receive(ref ep);
udpc.Close();
resp = new int[recv.Length];
for (int i = 0; i < resp.Length; i++)
resp[i] = Convert.ToInt32(recv[i]);
int status = resp[3];
if (status != 128) throw new Exception(string.Format("{0}", status));
int answers = resp[7];
if (answers == 0) throw new Exception("No results");
int pos = domain.Length + 18;
if (qtype == "15") // MX record
{
while (answers > 0)
{
int preference = resp[pos + 13];
pos += 14; //offset
string str = GetMXRecord(pos, out pos);
context.Response.Write(string.Format("{0}: {1}\n", preference, str));
answers--;
}
}
else if (qtype == "1") // A record
{
while (answers > 0)
{
pos += 11; //offset
string str = GetARecord(ref pos);
context.Response.Write(string.Format("{0}\n", str));
answers--;
}
}
}
//------------------------------------------------------
private string GetARecord(ref int start)
{
StringBuilder sb = new StringBuilder();
int len = resp[start];
for (int i = start; i < start + len; i++)
{
if (sb.Length > 0) sb.Append(".");
sb.Append(resp[i + 1]);
}
start += len + 1;
return sb.ToString();
}
private string GetMXRecord(int start, out int pos)
{
StringBuilder sb = new StringBuilder();
int len = resp[start];
while (len > 0)
{
if (len != 192)
{
if (sb.Length > 0) sb.Append(".");
for (int i = start; i < start + len; i++)
sb.Append(Convert.ToChar(resp[i + 1]));
start += len + 1;
len = resp[start];
}
if (len == 192)
{
int newpos = resp[start + 1];
if (sb.Length > 0) sb.Append(".");
sb.Append(GetMXRecord(newpos, out newpos));
start++;
break;
}
}
pos = start + 1;
return sb.ToString();
}
//------------------------------------------------------
public bool IsReusable { get { return false; } }
}
My approach was to use nslookup.exe to retreive the MX record.
The solution is not as fancy as rewriting whole DNS or using a System DLL -> but it works, with a little amount of lines.
To get things right, this code >just works< it's not ressource efficient nor fast and has a lots of room for improvment (multiple hostnames, async, more usefull return value,adding the priority):
static List<string> GetMxRecords(string host){
ProcessStartInfo nslookup_config = new ProcessStartInfo("nslookup.exe");
nslookup_config.RedirectStandardInput = true;
nslookup_config.RedirectStandardOutput = true;
nslookup_config.RedirectStandardError = true;
nslookup_config.UseShellExecute = false;
var nslookup = Process.Start(nslookup_config);
nslookup.StandardInput.WriteLine("set q=mx");
nslookup.StandardInput.WriteLine(host);
nslookup.StandardInput.WriteLine("exit");
List<string> lines = new List<string>();
while (!nslookup.StandardOutput.EndOfStream)
{
string l = nslookup.StandardOutput.ReadLine();
if (l.Contains("internet address ="))
{
while (l.Contains("\t\t"))
{
l = l.Replace("\t\t", "\t");
}
lines.Add(l.Replace("\tinternet address = ","="));
}
}
nslookup.Close();
return lines;
}
Should be working international, since nslookup does not support any translation (I'm working on a German machine and I'm getting english output).
The result are strings like this:
alt4.gmail-smtp-in.l.google.com=74.125.28.27
alt2.gmail-smtp-in.l.google.com=74.125.200.27
alt1.gmail-smtp-in.l.google.com=209.85.233.26
gmail-smtp-in.l.google.com=66.102.1.27
alt3.gmail-smtp-in.l.google.com=108.177.97.27
The accepted answer doesn't work for .NET framework < 4.5, so would suggest that those of you who can't use ARSOFT.Tools can use DNDNs from https://dndns.codeplex.com
Given below is a console application that returns the MX record for a given domain modifying their examples.
using System;
using System.Net.Sockets;
using DnDns.Enums;
using DnDns.Query;
using DnDns.Records;
namespace DnDnsExamples
{
class Program
{
static void Main(string[] args)
{
DnsQueryRequest request3 = new DnsQueryRequest();
DnsQueryResponse response3 = request3.Resolve("gmail.com", NsType.MX, NsClass.INET, ProtocolType.Tcp);
OutputResults(response3);
Console.ReadLine();
}
private static void OutputResults(DnsQueryResponse response)
{
foreach (IDnsRecord record in response.Answers)
{
Console.WriteLine(record.Answer);
Console.WriteLine(" |--- RDATA Field Length: " + record.DnsHeader.DataLength);
Console.WriteLine(" |--- Name: " + record.DnsHeader.Name);
Console.WriteLine(" |--- NS Class: " + record.DnsHeader.NsClass);
Console.WriteLine(" |--- NS Type: " + record.DnsHeader.NsType);
Console.WriteLine(" |--- TTL: " + record.DnsHeader.TimeToLive);
Console.WriteLine();
}
}
}
}
Here is a Class I use to look up MX records only.
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections.Specialized;
namespace Mx.Dns
{
public class Query
{
//Build a DNS query buffer according to RFC 1035 4.1.1 e 4.1.2
private readonly int id;
private readonly int flags;
private readonly int QDcount;
private readonly int ANcount;
private readonly int NScount;
private readonly int ARcount;
private readonly string Qname;
private readonly int Qtype;
private readonly int Qclass;
public byte[] buf;
public Query(int ID, string query, int qtype)
{
//init vectors with given + default values
id = ID;
flags = 256;
QDcount = 1;
ANcount = 0;
NScount = 0;
ARcount = 0;
Qname = query;
Qtype = qtype;
Qclass = 1; //Internet = IN = 1
//build a buffer with formatted query data
//header information (16 bit padding
buf = new byte[12 + Qname.Length + 2 + 4];
buf[0] = (byte)(id / 256);
buf[1] = (byte)(id - (buf[0] * 256));
buf[2] = (byte)(flags / 256);
buf[3] = (byte)(flags - (buf[2] * 256));
buf[4] = (byte)(QDcount / 256);
buf[5] = (byte)(QDcount - (buf[4] * 256));
buf[6] = (byte)(ANcount / 256);
buf[7] = (byte)(ANcount - (buf[6] * 256));
buf[8] = (byte)(NScount / 256);
buf[9] = (byte)(NScount - (buf[8] * 256));
buf[10] = (byte)(ARcount / 256);
buf[11] = (byte)(ARcount - (buf[10] * 256));
//QNAME (RFC 1035 4.1.2)
//no padding
string[] s = Qname.Split('.');
int index = 12;
foreach (string str in s) {
buf[index] = (byte)str.Length;
index++;
byte[] buf1 = Encoding.ASCII.GetBytes(str);
buf1.CopyTo(buf, index);
index += buf1.Length;
}
//add root domain label (chr(0))
buf[index] = 0;
//add Qtype and Qclass (16 bit values)
index = buf.Length - 4;
buf[index] = (byte)(Qtype / 256);
buf[index + 1] = (byte)(Qtype - (buf[index] * 256));
buf[index + 2] = (byte)(Qclass / 256);
buf[index + 3] = (byte)(Qclass - (buf[index + 2] * 256));
}
}
public class C_DNSquery
{
public StringCollection result = new StringCollection();
public int Error = 0;
public string ErrorTxt = "undefined text";
public bool Done = false;
public UdpClient udpClient;
private string DNS;
private string Query;
private int Qtype;
public bool IS_BLACKLIST_QUERY = false;
public C_DNSquery(string IPorDNSname, string query, int type)
{
DNS = IPorDNSname;
Query = query;
Qtype = type;
}
public void doTheJob()
{
//check if provided DNS contains an IP address or a name
IPAddress ipDNS;
IPHostEntry he;
try {
//try to parse an IPaddress
ipDNS = IPAddress.Parse(DNS);
} catch (FormatException ) {
// Console.WriteLine(e);
//format error, probably is a FQname, try to resolve it
try {
//try to resolve the hostname
he = Dns.GetHostEntry(DNS);
} catch {
//Error, invalid server name or address
Error = 98;
ErrorTxt = "Invalid server name:" + DNS;
Done = true;
return;
}
//OK, get the first server address
ipDNS = he.AddressList[0];
}
//Query the DNS server
//our current thread ID is used to match the reply with this process
Query myQuery = new Query(System.Threading.Thread.CurrentThread.ManagedThreadId, Query, Qtype);
//data buffer for query return value
Byte[] recBuf;
//use UDP protocol to connect
udpClient = new UdpClient();
do {
try {
//connect to given nameserver, port 53 (DNS)
udpClient.Connect(DNS, 53);
//send query
udpClient.Send(myQuery.buf, myQuery.buf.Length);
//IPEndPoint object allow us to read datagrams..
//..selecting only packet coming from our nameserver and port
IPEndPoint RemoteIpEndPoint = new IPEndPoint(ipDNS, 53);
//Blocks until a message returns on this socket from a remote host.
recBuf = udpClient.Receive(ref RemoteIpEndPoint);
udpClient.Close();
} catch (Exception e) {
//connection error, probably a wrong server address
udpClient.Close();
Error = 99;
ErrorTxt = e.Message + "(server:" + DNS + ")";
Done = true;
return;
}
//repeat until we get the reply with our threadID
} while (System.Threading.Thread.CurrentThread.ManagedThreadId != ((recBuf[0] * 256) + recBuf[1]));
//Check the DNS reply
//check if bit QR (Query response) is set
if (recBuf[2] < 128) {
//response byte not set (probably a malformed packet)
Error = 2;
ErrorTxt = "Query response bit not set";
Done = true;
return;
}
//check if RCODE field is 0
if ((recBuf[3] & 15) > 0) {
//DNS server error, invalid reply
switch (recBuf[3] & 15) {
case 1:
Error = 31;
ErrorTxt = "Format error. The nameserver was unable to interpret the query";
break;
case 2:
Error = 32;
ErrorTxt = "Server failure. The nameserver was unable to process the query.";
break;
case 3:
Error = 33;
ErrorTxt = "Name error. Check provided domain name!!";
break;
case 4:
Error = 34;
ErrorTxt = "Not implemented. The name server does not support the requested query";
break;
case 5:
Error = 35;
ErrorTxt = "Refused. The name server refuses to reply for policy reasons";
break;
default:
Error = 36;
ErrorTxt = "Unknown. The name server error code was: " + Convert.ToString((recBuf[3] & 15));
break;
}
Done = true;
return;
}
//OK, now we should have valid header fields
int QDcnt, ANcnt, NScnt, ARcnt;
int index;
QDcnt = (recBuf[4] * 256) + recBuf[5];
ANcnt = (recBuf[6] * 256) + recBuf[7];
NScnt = (recBuf[8] * 256) + recBuf[9];
ARcnt = (recBuf[10] * 256) + recBuf[11];
index = 12;
//sometimes there are no erros but blank reply... ANcnt == 0...
if (ANcnt == 0) { // if blackhole list query, means no spammer !!//if ((ANcnt == 0) & (IS_BLACKLIST_QUERY == false))
//error blank reply, return an empty array
Error = 4;
ErrorTxt = "Empty string array";
Done = true;
return;
}
//Decode received information
string s1;
// START TEST
s1 = Encoding.ASCII.GetString(recBuf, 0, recBuf.Length);
// END TEST
if (QDcnt > 0) {
//we are not really interested to this string, just parse and skip
s1 = "";
index = parseString(recBuf, index, out s1);
index += 4; //skip root domain, Qtype and QClass values... unuseful in this contest
}
if (IS_BLACKLIST_QUERY) {
// get the answers, normally one !
// int the four last bytes there is the ip address
Error = 0;
int Last_Position = recBuf.Length - 1;
result.Add(recBuf[Last_Position - 3].ToString() + "." + recBuf[Last_Position - 2].ToString() + "." + recBuf[Last_Position - 1].ToString() + "." + recBuf[Last_Position].ToString());
Done = true;
return;
}
int count = 0;
//get all answers
while (count < ANcnt) {
s1 = "";
index = parseString(recBuf, index, out s1);
//Qtype
int QType = (recBuf[index] * 256) + recBuf[index + 1];
index += 2;
s1 += "," + QType.ToString();
//QClass
int QClass = (recBuf[index] * 256) + recBuf[index + 1];
index += 2;
s1 += "," + QClass.ToString();
//TTL (Time to live)
uint TTL = (recBuf[index] * 16777216u) + (recBuf[index + 1] * 65536u) + (recBuf[index + 2] * 256u) + recBuf[index + 3];
index += 4;
s1 += "," + TTL.ToString();
int blocklen = (recBuf[index] * 256) + recBuf[index + 1];
index += 2;
if (QType == 15) {
int MXprio = (recBuf[index] * 256) + recBuf[index + 1];
index += 2;
s1 += "," + MXprio.ToString();
}
string s2;
index = parseString(recBuf, index, out s2);
s1 += "," + s2;
result.Add(s1);
count++;
}
Error = 0;
Done = true;
}
private int parseString(byte[] buf, int i, out string s)
{
int len;
s = "";
bool end = false;
while (!end) {
if (buf[i] == 192) {
//next byte is a pointer to the string, get it..
i++;
s += getString(buf, buf[i]);
i++;
end = true;
} else {
//next byte is the string length
len = buf[i];
i++;
//get the string
s += Encoding.ASCII.GetString(buf, i, len);
i += len;
//check for the null terminator
if (buf[i] != 0) {
//not null, add a point to the name
s += ".";
} else {
//null char..the string is complete, exit
end = true;
i++;
}
}
}
return i;
}
private string getString(byte[] buf, int i)
{
string s = "";
int len;
bool end = false;
while (!end) {
len = buf[i];
i++;
s += Encoding.ASCII.GetString(buf, i, len);
i += len;
if (buf[i] == 192) {
i++;
s += "." + getString(buf, buf[i]);
return s;
}
if (buf[i] != 0) {
s += ".";
} else {
end = true;
}
}
return s;
}
}
}
Here is how you use it.
/// <summary>
/// Get the MX from the domain address.
/// </summary>
public static string getMXrecord(string domain)
{
domain = domain.Substring(domain.IndexOf('#') + 1);
string LocalDNS = GetDnsAdress().ToString();
Console.WriteLine("domain: " + domain);
// resolv the authoritative domain (type=2)
C_DNSquery DnsQry = new C_DNSquery(LocalDNS, domain, 2);
Thread t1 = new Thread(new ThreadStart(DnsQry.doTheJob));
t1.Start();
int timeout = 20;
while ((timeout > 0) & (!DnsQry.Done)) {
Thread.Sleep(100);
timeout--;
}
if (timeout == 0) {
if (DnsQry.udpClient != null) {
DnsQry.udpClient.Close();
}
t1.Abort();
DnsQry.Error = 100;
}
string[] ns1;
string MyNs = "";
if (DnsQry.Error == 0) {
ns1 = DnsQry.result[0].Split(',');
MyNs = ns1[4];
t1.Abort();
} else {
t1.Abort();
MyNs = LocalDNS;
}
// Resolve MX (type = 15)
DnsQry = new C_DNSquery(MyNs, domain, 15);
Thread t2 = new Thread(new ThreadStart(DnsQry.doTheJob));
t2.Start();
timeout = 20;
string TTL = "";
string MXName = "";
Int32 preference = 9910000;
while ((timeout > 0) & (!DnsQry.Done)) {
Thread.Sleep(100);
timeout--;
}
if (timeout == 0) {
if (DnsQry.udpClient != null) {
DnsQry.udpClient.Close();
}
t2.Abort();
DnsQry.Error = 100;
}
if (DnsQry.Error == 0) {
if (DnsQry.result.Count == 1) {
string[] ns2 = DnsQry.result[0].Split(',');
MXName = ns2[5];
TTL = ns2[3];
preference = Int32.Parse(ns2[4]);
Console.WriteLine("domaine: {0} MX: {1} time: {2} pref: {3} ttl: {4}", domain.Substring(domain.IndexOf('#') + 1), MXName,
DateTime.Now, preference, TTL);
} else {
for (int indns = 0; indns <= DnsQry.result.Count - 1; indns++) {
string[] ns2 = DnsQry.result[indns].Split(',');
if (Int32.Parse(ns2[4]) < preference) {
MXName = ns2[5];
TTL = ns2[3];
preference = Int32.Parse(ns2[4]);
Console.WriteLine("domain: {0} MX: {1} time: {2} pref: {3} ttl: {4}", domain.Substring(domain.IndexOf('#') + 1), MXName,
DateTime.Now, preference, TTL);
}
}
}
}
return MXName;
}
I wrote a simply URL for that means
https://devselz.com/social/sign/buttons/dashboard/default.aspx?a=ciee&email=emailaddresstocheckifexistsornot#anydomain.com
Do not abuse
Return 1 if email exists or may exist, 0 if not
Works great in order to check:
gmail and gmail pro (domains not #gmail) accounts.
hotmail
For others like yahoo always returns 1
You can use this open source library to do almost any kind of query you would usually need.
Usage:
DnsClient dnsClient = new DnsClient();
string mxDomain = dnsClient.ResolveMX("example.com");
string mxDomainIP = dnsClient.ResolveMX("example.com", true);
string mxDomainIPv6 = dnsClient.ResolveMX("example.com", true, true);