c# If statement always returns false - c#

I'm currently developing a small server/client application for a personal project. The server is meant to be run in Linux under Mono while the client is being run from a Windows PC.
I have an issue where I am passing data to the server (In this case string value of "on" and "off") however an if statement is always returning a false value.
The code from the server is as follows
public void startServer() {
TcpListener listen = new TcpListener(serverIP, 10000);
listen.Start();
Console.Clear();
Console.WriteLine("IP Address = {0}", serverIP.ToString());
Console.WriteLine("Server is listening for connection");
Socket a = listen.AcceptSocket();
Console.WriteLine("Connection from {0}", a.RemoteEndPoint);
ASCIIEncoding respond = new ASCIIEncoding();
a.Send(respond.GetBytes("You are connected to LED Control Server"));
bool keepListening = true;
while (keepListening) {
byte[] b = new byte[1000];
a.Receive(b);
Console.WriteLine("Message Received from {0}, string: {1}", a.RemoteEndPoint, recData(b));
string serverMsg = procIns(recData(b));
a.Send(respond.GetBytes(serverMsg));
}
}
private string recData(byte[] b) //receiving data from the client {
int count = b.Length;
string message = "";
for (int a = 0; a < count; a++) {
message += Convert.ToChar(b[a]);
}
return message;
}
private string procIns(string instruction) {
string returnMsg;
Console.WriteLine(instruction.ToLower());
if (instruction.ToLower() == "on") {
FileGPIO gpio = new FileGPIO();
gpio.OutputPin(FileGPIO.enumPIN.gpio17, true);
returnMsg = "GPIO 17 1";
} else if (instruction.ToLower() == "off") {
FileGPIO gpio = new FileGPIO();
gpio.OutputPin(FileGPIO.enumPIN.gpio17, false);
returnMsg = "GPIO 17 0";
} else {
returnMsg = "Invalid Command";
}
return returnMsg;
}
The cause for the if statement in procIns method returning false is escaping me, if anyone could offer any advice I would appreciate it!

I would guess it would have to be padded spaces. Try this instead...
if (instruction.Trim().ToLower() == "on")

while (keepListening) {
byte[] b = new byte[1000];
int bytesRcvd = a.Receive(b);
Console.WriteLine("Message Received from {0}, string: {1}", a.RemoteEndPoint, recData(b));
string serverMsg = procIns(recData(b, bytesRcvd ));
a.Send(respond.GetBytes(serverMsg));
}
a.Receive(b) method returns number of bytes received. You can store the value in some variable and pass the variable to recData method.
private string recData(byte[] b, int bytesRcvd) {
string message = "";
for (int a = 0; a < bytesRcvd; a++) {
message += Convert.ToChar(b[a]);
}
return message;
}
The number of bytes received will help in truncating the extra values in byte array.

Related

Trying to update a ListView in a WinForm App from Task C#

I am having problems updating a ListView on C# WinForm. The application is a test harness which connects to a TCP Server and receives a data stream. The test harness will then be used to create multiple connections to the server to do load testing. Each task is started using the following command where the number of task is entered on the form:
for (int i = 0; i < noTasks; i++)
{
bool saveAudio = noTasksCheckedListBox.GetItemCheckState(i) == CheckState.Checked; // true : false;
taskArray[i] = Task.Run(() => SendMessage((initId + i).ToString(), saveAudio, audioServerIP));
}
The SendMessage function creates the TCP client connection and creates a AsyncCallBack to process the incoming stream.
void SendMessage(string id, bool saveWav, string serverIP)
{
TcpClient tcpclientAudio = new TcpClient();
string message = "GET /msg?id=" + id + "&type=0 HTTP/1.1\r\n";
NetworkObject audioObj = new NetworkObject
{
tcp = tcpclientAudio,
ConnectionType = FileType.Audio,
URL = message
};
if (saveWav)
{
tcpclientAudio.BeginConnect(IPAddress.Parse(serverIP), 8008, new AsyncCallback(CallBackConnectMethod01), audioObj);
}
else
{
tcpclientAudio.BeginConnect(IPAddress.Parse(serverIP), 8008, new AsyncCallback(CallBackConnectMethod02), audioObj);
}
}
The only difference between the CallBackConnctMethod is that 02 save the data to a file.
void CallBackConnectMethod02(IAsyncResult result)
{
NetworkObject obj = (NetworkObject)result.AsyncState;
TcpClient tcp = obj.tcp;
NetworkStream ns = tcp.GetStream();
startedProcessCount++;
int thisTask = startedProcessCount;
byte[] buffer = new byte[2048];
string message = obj.URL;
byte[] request = Encoding.ASCII.GetBytes(message);
ns.Write(request, 0, request.Length);
ns.Read(buffer, 0, 1000);
RefreshTable(thisTask, "Incoming", null);
......
}
When debugging the app goes to the RefreshTable function a disappears when it goes in to the delegate section.
private void RefreshTable(int taskNo, string status, string misc)
{
if (this.tasksListView.InvokeRequired)
{
this.Invoke((MethodInvoker) delegate {
DateTime nowDateTime = DateTime.Now;
string now = nowDateTime.Year.ToString("D4") + nowDateTime.Month.ToString("D2") + nowDateTime.Day.ToString("D2") + "-" + nowDateTime.Hour.ToString("D2") + nowDateTime.Minute.ToString("D2") + nowDateTime.Second.ToString("D2");
string taskId = "Task-" + taskNo.ToString("D3");
if (status == "Incoming")
{
ListViewItem taskLVI = tasksListView.Items.Add(taskId);
taskLVI.SubItems.Add(now);
taskLVI.SubItems.Add(" ");
taskLVI.SubItems.Add(" ");
if (string.IsNullOrEmpty(misc))
taskLVI.SubItems.Add(" ");
else
taskLVI.SubItems.Add(misc);
taskLVI.SubItems.Add(" ");
}
else
{
switch (status)
{
case "Lost":
case "Completed":
case "Exception":
ListViewItem listViewItem = null;
for (int i = 0; i < tasksListView.Items.Count; i++)
{
if (tasksListView.Items[i].SubItems[0].Text == taskId)
{
listViewItem = tasksListView.Items[i];
break;
}
}
if (listViewItem != null)
ToListViewItem(listViewItem, status, misc, now);
break;
default:
break;
}
}
tasksListView.Refresh();
});
}
}

Receive messsages off all sockets without looping through all sockets

I am writing a messaging application using C# and unity for my a level project, it is using a tcp client-sever model. I have created a list of sockets that can receive messages, but I have to specify the socket to receive the message from, this is fine for testing when i only have 1 client, but I need to be able to handle more connections, and looping through each socket to try and receive a message from it seems very inefficient and slow.
My question is: how can I receive messages from multiple clients without using the aforementioned method?
I'm going to post the specific sections, and then the entire code so you understand what I'm doing.
This is the thread that deals with receiving the data form the socket
public static void Thread1()
{
for (int i = 0; i <= 2; i++)
{
byte[] b = new byte[155];
///////// I need to specify the socket to receive from////////
int k = counter.numbers1[counter.i2].Receive(b);
//////////////////////////////////////////////////////////////
string k1 = "";
for (int i3 = 0; i3 < k; i3++)
k1 = k1 + Convert.ToChar(b[i3]);
Console.WriteLine(k1);
string sender_endpoint = k1.Substring(0, 21); ;
string receiver_endpoint = k1.Substring(22, 21);
string message = k1.Substring(44, 100);
string msgtype = k1.Substring(145, 1);
Console.WriteLine(k1.Length);
Console.WriteLine(sender_endpoint);
Console.WriteLine(receiver_endpoint);
Console.WriteLine(message);
Console.WriteLine(msgtype);
if (msgtype == "0") //message
{
Console.WriteLine("000");
}
else if (msgtype == "1") //command
{
Console.WriteLine("111");
}
}
}
The full server code is:
namespace server
{
static class counter
{
public static int i2 = 0;//main listener
public static int i4 = 0;//port number
public static List<TcpListener> numbers = new List<TcpListener>();//listeners
public static List<Socket> numbers1 = new List<Socket>();//sockets
}
class server_code
{
public static void Main()
{
string xyz123 = "x";
Thread thread3 = new Thread(new ThreadStart(Thread3));
Thread test_thread = new Thread(() => Test_Thread (xyz123));
thread3.Start();
}
public static void Thread1()
{
//message reactions
for (int i = 0; i <= 2; i++)
{
byte[] b = new byte[155];
int k = counter.numbers1[counter.i2].Receive(b);
string k1 = "";
for (int i3 = 0; i3 < k; i3++)
k1 = k1 + Convert.ToChar(b[i3]);
Console.WriteLine(k1);
string sender_endpoint = k1.Substring(0, 21); ;
string receiver_endpoint = k1.Substring(22, 21);
string message = k1.Substring(44, 100);
string msgtype = k1.Substring(145, 1);
Console.WriteLine(k1.Length);
Console.WriteLine(sender_endpoint);
Console.WriteLine(receiver_endpoint);
Console.WriteLine(message);
Console.WriteLine(msgtype);
if (msgtype == "0") //message
{
Console.WriteLine("000");
}
else if (msgtype == "1") //command
{
Console.WriteLine("111");
}
}
}
public static void Thread2()
{
//client message receiver
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
IPAddress ipAd = IPAddress.Parse(ip.ToString());
counter.numbers.Add(null);
counter.numbers1.Add(null);
Console.WriteLine("");
Socket xyz1 = counter.numbers[counter.i2].AcceptSocket();
counter.numbers1[counter.i2] = xyz1;
ASCIIEncoding asen = new ASCIIEncoding();
counter.numbers1[counter.i2].Send(asen.GetBytes(counter.numbers1[counter.i2].RemoteEndPoint.ToString()));
Console.WriteLine("Connection accepted from " + counter.numbers1[counter.i2].RemoteEndPoint);
Console.WriteLine("connecting to " + counter.numbers[counter.i2].LocalEndpoint);
//System.Threading.Thread.Sleep(3000);
Thread thread1 = new Thread(new ThreadStart(Thread1));
thread1.Start();
}
}
}
public static void Thread3()
{
//new clients acception
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
for (int i = 0; i <= 10; i++)
{
Console.WriteLine(ip.ToString());
IPAddress ipAd = IPAddress.Parse(ip.ToString());
TcpListener myList = new TcpListener(ipAd, 8080);
myList.Start();
Console.WriteLine("The local endpoint is :" + myList.LocalEndpoint);
Socket s = myList.AcceptSocket();//////////////////////////////////////////////
Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
Console.WriteLine("connecting to " + myList.LocalEndpoint);
ASCIIEncoding asen = new ASCIIEncoding();
counter.i2 = counter.i2 + i;
int portno = 8000;
s.Send(asen.GetBytes(portno.ToString()));
Console.WriteLine();
myList.Stop();
s.Close();
Thread thread2 = new Thread(new ThreadStart(Thread2));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
counter.numbers.Add(null);
TcpListener xyz = new TcpListener(ipAd, portno);
counter.numbers[counter.i2] = xyz;
//Console.WriteLine(counter.i4);//current portno
counter.numbers[counter.i2].Start();
Console.WriteLine("The local End point is :" + counter.numbers[counter.i2].LocalEndpoint);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
thread2.Start();
}
}
}
}
}
The full client code is:
public class cc : MonoBehaviour
{
public InputField NameField;
private string x;
private string y = "";
//private int z = 0;
static class ipadressnumber{
public static string ipadressno = "192.168.1.250";
}
public void Start(){
TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect(ipadressnumber.ipadressno,8080);
Stream stm = tcpclnt.GetStream();
byte[] bb=new byte[100];
int k=stm.Read(bb,0,100);
for (int i=0;i<k;i++){
y = y + Convert.ToChar(bb[i]);
}
//Debug.Log(y);
tcpclnt.Close();
}
public void OnSubmit()
{
x = NameField.text;
//Debug.Log(x);
try
{
System.Net.IPAddress ipad = IPAddress.Parse(ipadressnumber.ipadressno);
IPEndPoint ipLocalEndPoint = new IPEndPoint(ipad,8888);
//TcpClient clientSocket = new TcpClient(ipLocalEndPoint);
TcpClient tcpclnt1 = new TcpClient();
//Debug.Log(y);
tcpclnt1.Connect(ipadressnumber.ipadressno,int.Parse(y));
Stream stm = tcpclnt1.GetStream();
byte[] bb=new byte[100];
int k=stm.Read(bb,0,100);
string lclep = "";
for (int i=0;i<k;i++)
{
lclep = lclep + Convert.ToChar(bb[i]);
}
String str=x;
////////////format of message:(sender endpoint, recipient endpoint, message, message type, check sum/digit)
string message = "";
int strlen = 21;
int msglen = 100;
string msgtype = "0";// 0 = message, 1 = command
lclep = Convert.ToString(lclep);
Debug.Log (lclep);
while (strlen > lclep.Length)
{
Debug.Log('1');
lclep = lclep + "#";
}
string rmtep = "000.00.00.000:8000";
while (strlen > rmtep.Length)
{
Debug.Log ('2');
rmtep = rmtep + "#";
}
while (msglen > x.Length)
{
Debug.Log ('3');
x = x + "#";
}
message = message + lclep + ':' + rmtep + ':' + x + ':' + msgtype + ':';
Debug.Log(message);
ASCIIEncoding asen= new ASCIIEncoding();
byte[] ba = new byte[155];
ba=asen.GetBytes(message);
stm.Write(ba,0,ba.Length);
tcpclnt1.Close();
}
catch (Exception e) {
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
The output is this:
192.168.1.250
The local End point is :192.168.1.250:8080
Connection accepted from 192.168.1.250:54024
connecting to 192.168.1.250:8080
The local End point is :192.168.1.250:8000
192.168.1.250
The local End point is :192.168.1.250:8080
Connection accepted from 192.168.1.250:54055
connecting to 192.168.1.250:8000
192.168.1.250:54055##:000.00.00.000:8000###:message test 1 for stackoverflow####################################################################:0:
147
192.168.1.250:54055##
000.00.00.000:8000###
message test 1 for stackoverflow####################################################################
0
000
As you can see I don't get any errors so all I need is a way to receive messages form multiple clients.
It will be great to have a Minimal, Complete, and Verifiable example https://stackoverflow.com/help/mcve but I will give a possible solution to the problem I undertood: How to listen for multiple sockets and process their messages simultaneously.
You could start one thread for each socket you need, this Reader Thread would read the entire message and send to a thread safe list in another thread that I will call the Processing Thread. This last thread will apply your business logic to the data read by your socket, generate a response and send it to another thread: The Writer Thread.
Socker -> Readers -> Processor -> Writer
Don't start your threads like in your Thread3 and Thread2 methods, this demands too much CPU and can slow down your applocation. Create the threads beforehand and start then in the apropriate order.

Parallel.Foreach do not finish stream

For load testing purposes I need to simulate multiple users trying to login to a system at the same time. I have code written by another developer that can send a login request to the system. With an ok login it will also return other information in xml.
I've tried using Parallel.ForEach, but dont have any real experience with parallel programming:
Parallel.ForEach(clientList, client =>
{
RunTest(client);
});
public void RunTest(object data)
{
if (!(data is IGprsClient))
{
return;
}
_noRunningTests += 1;
IGprsClient gprsClient = data as IGprsClient;
DateTime startTime = DateTime.Now;
Log(gprsClient.Id, "Test started.");
bool result = gprsClient.StartTest(20000);
DateTime endTime = DateTime.Now;
TimeSpan diff = endTime - startTime;
if (result == false)
{
Log(gprsClient.Id, "Test failed.");
}
Log(gprsClient.Id, "Test took {0}ms. ", (int)diff.TotalMilliseconds);
_noRunningTests -= 1;
}
override public bool StartTest(int timeout)
{
_testStarted = true;
try
{
LogDebug("Trying to connect.");
_client = new TcpClient(ipAddress, port);
LogDebug("Connected.");
bool result = false;
//Todo: insert testcase into client
switch (TestCaseName)
{
case "LoginTEST":
var testCase = new LoginTEST(this);
result = testCase.Execute(user, pwd, phoneNum);
break;
default:
Log("Unknown test case: " + TestCaseName);
break;
}
_client.Close();
return result;
}
catch (Exception ex)
{
if (_client != null)
_client.Close();
Log(ex.Message);
return false;
}
}
Which in turn will send the request and read the response.
public bool Execute(string user, string pwd, string phoneNum)
{
SendDataListRequest(userId);
string requiredDataResponse = Client.ReadMsg();
return true;
}
Run test will send a request and reads the message like so:
public string ReadMsg()
{
int msgLength = -1;
var stream = _client.GetStream();
while (_testStarted)
{
int b = stream.ReadByte();
if (b == -1)
{
return "";
}
else if (b == 0x02 || msgLength == -1)
{
while (b != 0x02 && _testStarted)
{
b = stream.ReadByte(); // Finds the start token
if (b == -1)
{
return "";
}
}
msgLength = 0; // Starts collecting data
}
else if (b == 0x03)
{
byte[] encryptedMsg = Convert.FromBase64String(
Encoding.UTF8.GetString(byteBuffer, 0, msgLength));
byte[] decryptedMsg = SttCipher.DecryptMessage(encryptedMsg);
MemoryStream ms = new MemoryStream(decryptedMsg);
GZipStream gZipStream = new GZipStream(ms, CompressionMode.Decompress, true);
var bufLen = ReadAllBytesFromStream(gZipStream, decompressedBuffer);
gZipStream.Close();
string completeMsg = Encoding.UTF8.GetString(decompressedBuffer, 0, bufLen);
if (completeMsg.Length < 500)
LogDebug("Received XML-data:\n{0}", completeMsg);
else
LogDebug("Received XML-data: {0} bytes\n{1}...", completeMsg.Length, completeMsg.Substring(0, 500));
return completeMsg;
}
else
{
if (byteBuffer.Length <= msgLength)
{
throw new Exception("XML message too long!");
}
byteBuffer[msgLength] = (byte)b;
msgLength++;
}
}
return "";
}
Running one client is fine and will wait for the response. The issue is with several clients, the responses gets cut off. Leaving me with unclosed xml in the response.But I cant't figure out why. Does anyone have a reasonable explanation and/or a solution or a better way of doing it?

How to convert byte into Boolean

I want to convert a byte into Boolean. This is the code:
String text = textBox1.Text;
UdpClient udpc = new UdpClient(text,8899);
IPEndPoint ep = null;
while (true)
{
MessageBox.Show("Name: ");
string name = "Connected";
if (name == "") break;
byte[] sdata = Encoding.ASCII.GetBytes(name);
udpc.Send(sdata, sdata.Length);
if (udpc.Receive(ref ep)=null)
{
// MessageBox.Show("Host not found");
}
else
{
byte[] rdata = udpc.Receive(ref ep);
string job = Encoding.ASCII.GetString(rdata);
MessageBox.Show(job);
}
}
I want to convert this line of code into a Boolean:
udpc.Receive(ref ep);
You don't want to just compare the result with null at all... that way you would lose the actual data, and then call Receive again, effectively skipping the packet.
You should use:
byte[] data = udpc.Receive(ref ep);
if (data == null)
{
// Whatever
}
else
{
MessageBox.Show(Encoding.ASCII.GetBytes(data));
}
Also note that this code is broken:
string name = "Connected";
if (name == "") break;
How can name possibly be an empty string when you've just set it to "Connected"?
The UdpClient is naturally blocking until bytes are received.
This means that you shouldn't get data at all, assuming that you're looking for a way to indicate if you have received data, then once you move past the udpc.Recieve, you should return true.
I would also consider changing the code a bit as you will have some compilation issues with the = null statement as this does not translate into a compilable code expression.
There is also a problem with your if else statement as you're attempting to read from the UDP client which would consume the sent data.
Personally I would opt for a UDP socket, but in order to get you rolling I would change the code to something like this:
String text = textBox1.Text;
UdpClient udpc = new UdpClient(text,8899);
IPEndPoint ep = null;
while (true)
{
MessageBox.Show("Name: ");
string name = "Connected";
if (name == "") break; //This will never happen because you have already set the value
byte[] sdata = Encoding.ASCII.GetBytes(name);
int dataSent = 0;
try
{
dataSent = udpc.Send(sdata, sdata.Length);
}
catch(Exception e)
{
dataSent = 0;
//There is an exception. Probably the host is wrong
}
if (dataSent > 0)
{
try
{
byte[] rdata = udpc.Receive(ref ep);
if(rdata!=null && rdata.Length > 0)
{
string job = Encoding.ASCII.GetString(rdata);
MessageBox.Show(job)
//True here as we managed to recieve without going to the catch statement
//and we actually have data in the byte[]
}
else
{
MessageBox.Show("We did not recieve any data");
//False here, because the array was empty.
}
}
catch(Exception udpe)
{
//False here as we had a socket exception or timed out
MessageBox.Show(udpe.ToString());
}
}
}

spamassassin check score C# code

Is there a way to check the score in an ASP.Net application? A class or something similar for .Net? How about other Spam Filters out there.
--Edited
I am looking for a way to check the spam score of the email messages in C#.
Here is my super simplified "just check the score" code for connecting to a running Spam Assassin email check from C# which I wrote for http://elasticemail.com. Just setup SA to run on a server and set the access permissions.
Then you can use this code to call it:
public class SimpleSpamAssassin
{
public class RuleResult
{
public double Score = 0;
public string Rule = "";
public string Description = "";
public RuleResult() { }
public RuleResult(string line)
{
Score = double.Parse(line.Substring(0, line.IndexOf(" ")).Trim());
line = line.Substring(line.IndexOf(" ") + 1);
Rule = line.Substring(0, 23).Trim();
Description = line.Substring(23).Trim();
}
}
public static List<RuleResult> GetReport(string serverIP, string message)
{
string command = "REPORT";
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0} SPAMC/1.2\r\n", command);
sb.AppendFormat("Content-Length: {0}\r\n\r\n", message.Length);
sb.AppendFormat(message);
byte[] messageBuffer = Encoding.ASCII.GetBytes(sb.ToString());
using (Socket spamAssassinSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
spamAssassinSocket.Connect(serverIP, 783);
spamAssassinSocket.Send(messageBuffer);
spamAssassinSocket.Shutdown(SocketShutdown.Send);
int received;
string receivedMessage = string.Empty;
do
{
byte[] receiveBuffer = new byte[1024];
received = spamAssassinSocket.Receive(receiveBuffer);
receivedMessage += Encoding.ASCII.GetString(receiveBuffer, 0, received);
}
while (received > 0);
spamAssassinSocket.Shutdown(SocketShutdown.Both);
return ParseResponse(receivedMessage);
}
}
private static List<RuleResult> ParseResponse(string receivedMessage)
{
//merge line endings
receivedMessage = receivedMessage.Replace("\r\n", "\n");
receivedMessage = receivedMessage.Replace("\r", "\n");
string[] lines = receivedMessage.Split('\n');
List<RuleResult> results = new List<RuleResult>();
bool inReport = false;
foreach (string line in lines)
{
if (inReport)
{
try
{
results.Add(new RuleResult(line.Trim()));
}
catch
{
//past the end of the report
}
}
if (line.StartsWith("---"))
inReport = true;
}
return results;
}
}
Usage is quite easy:
List<RuleResult> spamCheckResult = SimpleSpamAssassin.GetReport(IP OF SA Server, FULL Email including headers);
It will return the list of spam check rules you hit and the resulting score impact.
I am not exactly sure if that's what you are searching for, but there is a C# wrapper that simplifies the communication with a SpamAssassin server on Code Project:
A C# Wrapper for the SpamAssassin Protocol
Hope that helps!

Categories