I am currently facing a problem related to SMSlib for .NET library (you can download it at http://www.smslib.org/)
btw I used SendMessage example (you can find it in ...\Examples\SendMessage) found in the library, and tried to compile and run it using VS2012...it worked fine , but it never succeeded when I tried to restart the services again after adding a little bit code to restart the services into it...
Do you know how to make the services restart properly?
btw part of the code is as follows :
try
{
Console.WriteLine("Example: Read messages from a serial gsm modem.");
Console.WriteLine(Library.getLibraryDescription());
Console.WriteLine("Version: " + Library.getLibraryVersion());
// Start the COM listening thread.
new Thread(new ThreadStart(com1.Run)).Start();
// Lets set some callbacks.
srv.setInboundMessageNotification(new InboundNotification());
srv.setCallNotification(new CallNotification());
srv.setGatewayStatusNotification(new GatewayStatusNotification());
// Create the Gateway representing the serial GSM modem.
// Due to the Comm2IP bridge, in SMSLib for .NET all modems are considered IP modems.
IPModemGateway gateway = new IPModemGateway("modem.com14", "127.0.0.1", 12000, "Huawei","E173");
gateway.setIpProtocol(ModemGateway.IPProtocols.BINARY);
// Set the modem protocol to PDU (alternative is TEXT). PDU is the default, anyway...
gateway.setProtocol(AGateway.Protocols.PDU);
// Do we want the Gateway to be used for Inbound messages?
gateway.setInbound(true);
// Do we want the Gateway to be used for Outbound messages?
gateway.setOutbound(true);
// Add the Gateway to the Service object.
srv.addGateway(gateway);
// Similarly, you may define as many Gateway objects, representing
// various GSM modems, add them in the Service object and control all of them.
// Start! (i.e. connect to all defined Gateways)
srv.startService();
// Printout some general information about the modem.
Console.WriteLine();
Console.WriteLine("Modem Information:");
Console.WriteLine(" Manufacturer: " + gateway.getManufacturer());
Console.WriteLine(" Model: " + gateway.getModel());
Console.WriteLine(" Serial No: " + gateway.getSerialNo());
Console.WriteLine(" SIM IMSI: " + gateway.getImsi());
Console.WriteLine(" Signal Level: " + gateway.getSignalLevel() + "dBm");
Console.WriteLine(" Battery Level: " + gateway.getBatteryLevel() + "%");
Console.WriteLine();
// Send one message.
// Remember to change the recipient!
OutboundMessage msg = new OutboundMessage("0952998989", "Hello from SMSLib for .NET");
srv.sendMessage(msg);
Console.WriteLine(msg);
Console.WriteLine("Press <ENTER> to terminate...");
Console.In.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
finally
{
com1.Stop();
srv.stopService();
// Start! (i.e. connect to all defined Gateways)
srv.startService();
new Thread(new ThreadStart(com1.Run)).Start();
}
You should not call com1.Stop(); until you're completely done with starting/stopping the service. Just leave the listener active.
E.g.
finally
{
srv.stopService();
srv.startService();
srv.stopService();
srv.startService();
srv.stopService();
srv.startService();
srv.stopService();
srv.startService();
srv.stopService();
// ... and finally ...
com1.Stop();
}
Related
I have a SignalR server which sends certain messages to all the clients connected to it. I have created two sample clients one in UWP and another one is a simple console application in C#. I simply log a message once the client's method is called from SignalR.
Dramatically, the console application logs the data as soon as the server sends, but the UWP application adds a delay of about 6-30 seconds in it. Although it triggers frequently sometimes, it is able to reproduce the issue 6 out of 10 times.
Below is the code for the UWP client, similarly, I have logged message in console application.
async Task SetupSignalR()
{
var conn = new HubConnection(baseUrl);
Writer.Text += (string.Format("Creating hub proxy with :{0}\n", baseUrl));
var proxy = conn.CreateHubProxy("PumpStatusHub");
Writer.Text += "Starting Connection\n";
try
{
conn.Start().Wait();
Writer.Text += "Connection started\n";
proxy.Invoke("OpenPortReading").Wait();//, UserName, TextBoxMessage.Text);
Writer.Text += "Port invoked\n";
proxy.On<string>("ReadUdpData", OnMessage);
}
catch (HttpRequestException ex)
{
Writer.Text += "Unable to connect to server: Start server
before connecting clients.\n";
Writer.Text += ex.Message + "\n";
}
catch (Exception ex)
{
Writer.Text += ex.Message + "\n";
Task.Delay(3000).Wait();
SetupSignalR().Wait();
}
}
private void OnMessage(string obj)
{
Windows.ApplicationModel.Core.CoreApplication.MainView.
Dispatcher.RunAsync(CoreDispatcherPriority.High, (DispatchedHandler)(() =>
{
Writer.Text += string.Format("Message received: {0}\n"
, counter++);
}));
}
Any help would be highly appreciated. Thanks in advance.
I got this fixed by collaborating with SignalR developers and found an interesting thing that on using Server sent events as transport there was an issue with SignalR for UWP client which they are fixing.
I resolved the issue by using Long polling transport as Windows 7 does not support WebSockets.
Overview of Problem:
I need to connect to an IRC Server. Once connected, the program will send a message to the channel, and a response will occur over multiple lines back. I need to read these lines and store in a variable for later use. A special character at the end of the message (]) will define the end of the message over multiple lines. Once we have received this character, the IRC session should disconnect and processing should continue.
Situation:
I am using the Smartirc4net library. Calling irc.Disconnect() takes about 40 seconds to disconnect the session. Once we've received the ] character, the session should be disconnected, Listen() should not be blocking, and the rest of the program should continue to run.
Research:
I have found this: smartirc4net listens forever, can't exit thread, and I think it might be the same issue, however, I am unsure of what I need to do to resolve the problem.
Code:
public class IrcCommunicator
{
public IrcClient irc = new IrcClient();
string data;
public string Data { get { return data; } }
// this method we will use to analyse queries (also known as private messages)
public void OnQueryMessage(object sender, IrcEventArgs e)
{
data += e.Data.Message;
if (e.Data.Message.Contains("]"))
{
irc.Disconnect(); //THIS TAKES 40 SECONDS!!!
}
}
public void RunCommand()
{
irc.OnQueryMessage += new IrcEventHandler(OnQueryMessage);
string[] serverlist;
serverlist = new string[] { "127.0.0.1" };
int port = 6667;
string channel = "#test";
try
{
irc.Connect(serverlist, port);
}
catch (ConnectionException e)
{
// something went wrong, the reason will be shown
System.Console.WriteLine("couldn't connect! Reason: " + e.Message);
}
try
{
// here we logon and register our nickname and so on
irc.Login("test", "test");
// join the channel
irc.RfcJoin(channel);
irc.SendMessage(SendType.Message, "test", "!query");
// here we tell the IRC API to go into a receive mode, all events
// will be triggered by _this_ thread (main thread in this case)
// Listen() blocks by default, you can also use ListenOnce() if you
// need that does one IRC operation and then returns, so you need then
// an own loop
irc.Listen();
// when Listen() returns our IRC session is over, to be sure we call
// disconnect manually
irc.Disconnect();
}
catch (Exception e)
{
// this should not happen by just in case we handle it nicely
System.Console.WriteLine("Error occurred! Message: " + e.Message);
System.Console.WriteLine("Exception: " + e.StackTrace);
}
}
}
IrcBot bot = new IrcBot();
bot.RunCommand();
ViewBag.IRC = bot.Data;
As you can see, once this
Thank you for your time to look at this code and read my problem description. If you have any thoughts, or other suggestions, please let me know.
Mike
I was able to successfully disconnect straight away by calling RfcQuit() within OnQueryMessage(), before irc.Disconnect();
I am using the following function to stop my windows service (with a timeout):
public int StopService()
{
ServiceController service = new ServiceController(serviceName);
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
return 1;
}
catch (Exception ex)
{
logger.Log(LoggingLevel.Error,
this.GetType().Name + ":" + MethodBase.GetCurrentMethod().Name,
string.Format("{0}", ex.Message));
return -1;
}
}
I check the status of the service. And if it is not ServiceControllerStatus.Stopped I call this function.
I have tested and the program works when the status of the server is Running or Stopped. But I would like to know what happens when the status is other states such as StopPending, StartPending, etc. If I tell my service to stop while the state is one of the above, will the Stop command still do its job?
It depends on the service and what it permits at the time of the call to Stop().
At the Win32 level, each service must regularly call SetServiceStatus() to inform the Service Control Manager (SCM) what commands it will accept. Your call to Stop() will only succeed when the service has explicitly said that it allows that operation. In my experience, services in a pending state do not usually allow the normal range of operations so a call to Stop() will likely fail.
Note that it is easy to check what is permitted in C#, as illustrated in this sample code under the Examples heading. You can prefix your call to Stop() with CanStop(), and maybe wait a while if the service isn't quite ready to be stopped yet. Contingencies abound.
You can try like below, below example for StopPending ,
while (service.Status == ServiceControllerStatus.StopPending) //If it is stop pending, wait for it
{
System.Threading.Thread.Sleep(30 * 1000); // thread sleep for 30 seconds
service.Refresh(); // refreshing status
if (service.Status == ServiceControllerStatus.Stopped)
{
Comments = "Service " + serviceName + " stopped successfully. ";
}
}
Let me know whether it works or not. Please also provide if you have(had) any better solution
Recently, I was given an assignment...
"To develop a Windows Forms application which can be installed on various windows machines at an office or enterprise. There would be a database in just one machine(ALPHA machine).. This database would be used by applications on other Beta machines to access data. The application would itself manage to check if it is an Alpha or a Beta (Has Database file with it?) and hence has to act as a server or a client."
I can do everything except the Network and Inter-Application Communication requirements. So, I started to learn Socket Programming over the Internet and I have gone through this link...
The idea I am working on is...
To have the client send the message to server.
To have the server accept this message and put this message in queue.
Read the message to get Client's IP Address and the its Request for Data.
Apply this request on database and get the result.
Convert the result in string.
Send it to the requesting client.
I can manage to perform steps 3,4 & 5. I am stuck on 1, 2 & 6.
Towards this...
I have created a function for Server as well as for client who return the Sockets when called. I create a separate function as I like my code to be clean, tidy and understandable after years.
Check my code below...
For Server...
private Socket GetServerReady()
{
IPEndPoint RemoteEP = new IPEndPoint(IPAddress.Any, 8000);
Socket newSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
newSock.Connect(RemoteEP);
newSock.Listen(10);
return (newSock);
}
You will notice there is no Accept() method anywhere, This is because I wish to call it like below for further use...
Socket CltSock = GetServerReady().Accept();
The Code for Client is...
private Socket GetClientReady()
{
IPEndPoint RemoteEP = new IPEndPoint(IPAddress.Parse(txtBxHost2.Text.Trim()), 8000);
Socket ServerSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ServerSock.Connect(RemoteEP);
return (ServerSock);
}
Finally, The questions are....
"Where is the appropriate place to call the functions I wrote above?"
"Should I call the Server and Client Function in Form_Load() Event?"
"What must be the next step towards my main intention which is point 1,2 & 6 mentioned above?"
I don't expect the full code that I can just copy as it is. Just the correct procedure and a little detail over the concept would do.
I would be using just a single PC for testing purpose. Also, another limitation is, It would all be coded in a single application. I don't want to write two separate applications for client & server.
I hope I made it all clear for you to understand.
Thanks a Lot.
Awaiting the response.
I was struggling to get things done and somehow managed to get the solution.
Below is my solution:
Server Side code:
(I put this code in a function which loops back the execution if any exception is caught)
private void Looper()
{
int i = 0;
int AttemptCount = 1;
while (i == 0)
{
try
{
TcpListener tL = new TcpListener(Network.GetLocalIPAddress(), 56009);
tL.Start(10);
Socket tS = tL.AcceptSocket();
if (tS.Connected)
{
NetworkStream nS = new NetworkStream(tS);
StreamReader Reader = new StreamReader(nS);
Output = Reader.ReadToEnd().Trim();
Reader.Close();
nS.Close();
tS.Close();
tL.Stop();
//If Done, End Execution
i = 1;
}
else
{
MessageBox.Show("The connection to the client is broken or failed..!!\n\nPlease check connection and try again.","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
catch (SystemException ex)
{
//If Not, Loop Execution Again
if (MessageBox.Show("Exception: " + ex.Message + "\n\nAttempt Count: " + AttemptCount + "\n\nDo you want to terminate the transmission?", "Error", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes)
{
i = 1;
ResetTimer.Stop();
}
else
{
i = 0;
AttemptCount++;
}
}
}
}
When above function is called, The server waits to accept any incoming socket. If there is any error somewhere due to port re-usage or anything, It loops back itself and resets the server. (So, we don't have to manually call the server function again & again.)
Once the server accepts any incoming socket, the execution ends up successfully. Lot's of time we don't want to keep invoking server even after a successful reception. So, I, instead of calling this function in a button "click_event", I called it in a timer Tick_Event. So, the human need is eliminated at server side.
This leads to a problem. Once the server starts waiting to accept, It is in blocking mode.
It hangs all the processes and controls in same thread. So, I moved the call to above function to BackgroundWorker's "Do_Work" Event.
Check below Code:
private void GetServerReady()
{
if (!bW.IsBusy)
{
bW.RunWorkerAsync();
txtBxHistory.Text += "\r\n" + Output;
}
}
private void bW_DoWork(object sender, DoWorkEventArgs e)
{
Looper();
}
private void ResetTimer_Tick(object sender, EventArgs e)
{
GetServerReady();
}
"bW" is "BackgroundWorker".
"Output" is a variable I defined globally.
The reason we need a variable is that,
BackgroundWorker has its own thread to execute the code placed in its "Do_Work" Event. So, a TextBox from our application's thread can't be used by BackgroundWorker to store the received output. Doing this to a variable and then setting TextBox's Text property to this variable does the trick.
Client Side code:
private void btnSend_Click(object sender, EventArgs e)
{
TcpClient socketForServer;
try
{
socketForServer = new TcpClient(txtBxDestIP.Text.Trim(), 56009);
}
catch
{
MessageBox.Show("Failed to connect to server at " + txtBxDestIP.Text.Trim() + ":999", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
NetworkStream networkStream = socketForServer.GetStream();
StreamWriter streamWriter = new System.IO.StreamWriter(networkStream);
try
{
string InputString;
InputString = Network.GetLocalIPAddress() + ": " + txtBxData.Text;
streamWriter.Write(InputString);
streamWriter.Flush();
socketForServer.Close();
txtBxHistory.Text += "\r\nMe: " + txtBxData.Text.Trim();
txtBxData.Clear();
}
catch
{
MessageBox.Show("Exception reading from Server.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
streamWriter.Close();
networkStream.Close();
socketForServer.Close();
}
"txtBxDestIP" is a TextBox having the Destination IP address as Text.
"txtBxData" is a TextBox having the text to be sent.
This code works flawless for me. With above solution I can achieve all my motives from step 1 to 6 (Mentioned in the question above.)
I hope it helps others too. Please suggest if there is a better and efficient way to perform this.
Thanks.
Regards.
How do I detect when the internet is idle (no download/upload) using C#, and initiate a download when it is?
If you are waiting for a moment where there are no connections... you have to know that there are a lot of connections even when you think you are not using Internet.
Try giving a look at WireShark and Prcomon (from sysitnerals) to have an idea.
Notwork traffic
Note: if you are using .NET on Mac or Linux via Mono, you should know that this APIs don't port well to other operating systems. So, what I describe here is only for Windows.
If what you want is to have an idea of the traffic, you can try using System.Net.NetworkInformation.IPGlobalStatistics.
You can do so, like this:
var properties = IPGlobalProperties.GetIPGlobalProperties();
// IPGlobalStatistics for IPv4
var ipv4stat = properties.GetIPv4GlobalStatistics();
// IPGlobalStatistics for IPv6
var ipv6stat = properties.GetIPv6GlobalStatistics();
From the example at MSDN:
Console.WriteLine(" Forwarding enabled ...................... : {0}",
ipstat.ForwardingEnabled);
Console.WriteLine(" Interfaces .............................. : {0}",
ipstat.NumberOfInterfaces);
Console.WriteLine(" IP addresses ............................ : {0}",
ipstat.NumberOfIPAddresses);
Console.WriteLine(" Routes .................................. : {0}",
ipstat.NumberOfRoutes);
Console.WriteLine(" Default TTL ............................. : {0}",
ipstat.DefaultTtl);
Console.WriteLine("");
Console.WriteLine(" Inbound Packet Data:");
Console.WriteLine(" Received ............................ : {0}",
ipstat.ReceivedPackets);
Console.WriteLine(" Forwarded ........................... : {0}",
ipstat.ReceivedPacketsForwarded);
Console.WriteLine(" Delivered ........................... : {0}",
ipstat.ReceivedPacketsDelivered);
Console.WriteLine(" Discarded ........................... : {0}",
ipstat.ReceivedPacketsDiscarded);
Console.WriteLine(" Header Errors ....................... : {0}",
ipstat.ReceivedPacketsWithHeadersErrors);
Console.WriteLine(" Address Errors ...................... : {0}",
ipstat.ReceivedPacketsWithAddressErrors);
Console.WriteLine(" Unknown Protocol Errors ............. : {0}",
ipstat.ReceivedPacketsWithUnknownProtocol);
Console.WriteLine("");
Console.WriteLine(" Outbound Packet Data:");
Console.WriteLine(" Requested ........................... : {0}",
ipstat.OutputPacketRequests);
Console.WriteLine(" Discarded ........................... : {0}",
ipstat.OutputPacketsDiscarded);
Console.WriteLine(" No Routing Discards ................. : {0}",
ipstat.OutputPacketsWithNoRoute);
Console.WriteLine(" Routing Entry Discards .............. : {0}",
ipstat.OutputPacketRoutingDiscards);
Console.WriteLine("");
Console.WriteLine(" Reassembly Data:");
Console.WriteLine(" Reassembly Timeout .................. : {0}",
ipstat.PacketReassemblyTimeout);
Console.WriteLine(" Reassemblies Required ............... : {0}",
ipstat.PacketReassembliesRequired);
Console.WriteLine(" Packets Reassembled ................. : {0}",
ipstat.PacketsReassembled);
Console.WriteLine(" Packets Fragmented .................. : {0}",
ipstat.PacketsFragmented);
Console.WriteLine(" Fragment Failures ................... : {0}",
ipstat.PacketFragmentFailures);
Console.WriteLine("");
Is Internet Available?
If you need to get a notification when the Internet is avaliable, you can subscribe to System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged. That way you will get a notification event if the Internet is connected or disconnected (Don't forget to unsubscribe).
Example:
var handler = new NetworkAddressChangedEventHandler
(
(sender, args) =>
{
//handle notification
}
);
System.Net.NetworkInformation.NetworkChange += handler;
// Unsubscribe:
System.Net.NetworkInformation.NetworkChange -= handler;
You may be interested in knowing what Network adapters are Up or Down and how much traffic each one has... for that see below.
Idle & Idle time
Let's define "Idle". I would say "Idle" means that the Internet is available (check above), and if it hasn't been used for a given ammount of time.
So, the other thing you got to do is is calling NetworkInterface.GetAllNetworkInterfaces that will give you an array of System.Net.NetworkInformation.NetworkInterface on which you can call the method GetIPStatistics to get an IPStatistics object for that particular netowork interface. You can also read the OperationalStatus property to know if the particular interface is Up or not
Example:
NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
foreach (var adapter in adapters)
{
// Is Up, Down, something else?
Console.WriteLine(" {0} is {1}", adapter.Name, dapter.OperationalStatus);
var stats = adapter.GetIPStatistics();
// Read some properties
Console.WriteLine(" Bytes Recieved: {0}", stats.BytesReceived);
Console.WriteLine(" Bytes Sent: {0}", stats.BytesSent);
}
What you will need to do is store this information in a way you can query it, to check if it has changed:
// Fields
Dictionary<string, Tuple<long, long>> data
= new Dictionary<string, Tuple<long, long>>();
bool IsInternetIdle()
{
bool idle = true;
NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
foreach (var adapter in adapters)
{
var stats = adapter.GetIPStatistics();
Tuple<long, long> info;
if (!data.TryGetValue(adapter.Name, out info))
{
//New Adapter
info = new Tuple<long, long>
(
stats .BytesReceived,
stats .BytesSent
);
data.Add(adapter.Name, info);
}
else
{
if
(
info.Item1 != stats .BytesReceived
|| info.Item2 != stats .BytesSent
)
{
idle = false;
break;
}
}
}
//Console.WriteLine("Is Idle: {0}", idle.ToString());
return idle;
}
And add some logic to handle idle time:
// Fields
Stopwatch watch = new Stopwatch();
static TimeSpan? GetInternetIdleTime()
{
if (IsInternetIdle())
{
if (!watch.IsRunning)
{
watch.Start();
}
//Console.WriteLine("Idle Time: {0}", XmlConvert.ToString(watch.Elapsed));
return watch.Elapsed;
}
else
{
watch.Stop();
watch.Reset();
return null;
}
}
Example usage:
GetInternetIdleTime(); //preemptive call
Thread.Sleep(1000);
var result = GetInternetIdleTime();
if (result.HasValue)
{
Console.WriteLine("Idle time: {0}", result.Value);
}
else
{
Console.WriteLine("Not Idle");
}
Console.ReadKey();
Words of caution
Remember to unsubscribe your event handler.
This is intended to work on Windows only.
Remember that the first run of IsInternetIdle (described above) all the network adapters are new. You may want to do a preemptive call to GetInternetIdleTime (described above) before stating using them.
The methods IsInternetIdle and GetInternetIdleTime are intended to be used only when Internet is available. You could add checks to see if the individual network adapters are Up.
The result of GetInternetIdleTime described above is not the total time that the connections has been inactive, but the time since it was discovered that the connections are inactive. You may want to call GetInternetIdleTime in a timer (of if your application has a main loop - say, it's a game - you can call it with a given frequency).
If a netwokr adaptes is Active, it doesn't mean that it is using Internet. Maybe it is connected to some Intranet. There is no way to tell if "Internet" is reachable. You should check for conectivity with individual servers yourself. Don't know what to check? It can be problematic because DNS can be overrrided locally... but you can try example.or, InterNIC.net or even ntp.ord.
Alternative
Since this is for Windows anyway, you can try using WMI to the network adapters information, for that I'll refer you to Find only physical network adapters with WMI Win32_NetworkAdapter class by Mladen Prajdic.
Digging deeper
You can emulate what WireShark does by using PCapDotNet, you will find examples at CodeProject.com. Let me DuckDuckGo that for you.