I want to iterate UDP port from 5000 to 50xx
How can I check if a specific port is already open or free to use?
I use this code but it always returns false:
public bool PortIsUsed(int myport)
{
bool alreadyinuse = (from p in System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners() where p.Port == myport select p).Count() == 1;
return alreadyinuse;
}
Normally when asking for a shared resource such as UDP port numbers, asking "is this available right now?" is not productive. Whichever answer you get may become incorrect in the next microsecond, as another application could change something that invalidates the answer.
What you can do is ask the OS to listen on a specific port ("acquire" the resource). The OS will either say yes, and here's a handle or whatever, or no, some other process is using that particular port. Either way, you get an answer that you can definitively act on. (Specifically, if you get no for an answer, try a different port.)
Related
I'm developing an application by TAPI technology in C#.
Suppose that I want to make a call to an organization that has a central device. I want when the target machine answers the phone line, my app dials the second number that is an internal number to that organization. I don't know how to dial the second number.
For example I want to call +1234567890 and when the phone line is answered, I want to dial 101 that is an internal number. My app dial's the first part of number perfectly, but i don't know how to code the second part.
numberList = "001234567890#101".Split('#');
tapiManager = new TapiManager(ProjectName);
tapiManager.Initialize();
lineName = (tapiManager != null && tapiManager.Lines.Length > 0 ? tapiManager.Lines[0].Name : string.Empty);
tapiline = tapiManager.GetLineByName(lineName, true);
if (tapiline == null)
tapiline = tapiManager.GetLineByName(lineName, true);
if (!tapiline.IsOpen)
tapiline.Open(MediaModes.DataModem);
makeCallParams = new MakeCallParams();
makeCallParams.DialPause = 2000;
tapiCall = tapiline.MakeCall(numberList[0], null, makeCallParams);
As you see the last line of my code dials the first number, but I can't find a way to dial the second part.
Any ideas about how I can do that?
This very much depends on what this central device is and how it handles your call, so I'll give a few examples:
An older (think analogue) PBX/Appliance will likely accept any digits after it has accepted the call. This you can do by including pauses in your number (usually "." or "," or "p") so "001234567890,,,,,101" (warning: not all TAPI drivers will support this). How many pauses really depends on the speed this central device picks up, too few it will cut of a part of the number, too much and it might hangup.
An IVR or PBX trunk that is specifically configured for this kind of setup should simply accept the full number in the original call, strip off the root number "001234567890" and dial "101" itself (strip out the "#").
An IVR/Voicemail or some other system that play's a message like "Which extension do you wish to call?" usually only accept digits after the message starts or end (barge-in allowed or not). Detecting voice is notoriously difficult, your best bet here is just to guess how long the message is, wait and then put the "101" on the line. (i don't know the lib you are using but the function is probably called GenerateDigits)
so I have a kinda strange problem. I'm using LAN for the communication with a microcontroller. Everything was working perfect. Meaning: I can send and receive data. For receiving data I'm using a simple method, which is Thread.sleep(1) in a for loop in which I keep checking client.GetStream().DataAvailable for true while client is a TcpClient
Now, with one process I have to send and receive to the microcontroller with a higher Baud rate. I was using 9600 for all other operations and everythingwas fine. Now with 115200 client.GetStream().DataAvailableseems to always have the value false.
What could be the problem?
PS: Another way to communicate with the microcontroller (all chosen by user) is serial communication. This is still working fine with the higher Baud rate.
Here is a code snippet:
using (client = new TcpClient(IP_String, LAN_Port))`
{
client.SendTimeout = 200;
client.ReceiveTimeout = 200;
stream = client.GetStream();
.
.
bool OK = false;
stream.Write(ToSend, 0, ToSend.Length);
for (int j = 0; j < 1000; j++)
{
if (stream.DataAvailable)
{
OK = true;
break;
}
Thread.Sleep(1);
}
.
.
}
EDIT:
While monitoring the communication with a listing device I realized that the bits actually arrive and that the device actually answers. The one and only problem seem that the DataAvailable flag is not being raised. I should probably find another way to check data availability. Any ideas?
I've been trying to think of things I've seen that act this way...
I've seen serial chips that say they'll do 115,200, but actually won't. See what happens if you drop the baud rate one notch. Either way you'll learn something.
Some microcontrollers "bit-bang" the serial port by having the CPU raise and lower the data pin and essentially go through the bits, banging 1 or 0 onto the serial pin. When a byte comes in, they read it, and do the same thing.
This does save money (no serial chip) but it is an absolute hellish nightmare to actually get working reliably. 115,200 may push a bit-banger too hard.
This might be a subtle microcontroller problem. Say you have a receiving serial chip which asserts a pin when a byte has come in, usually something like DRQ* for "Data Request" (the * in DRQ* means a 0-volt is "we have a byte" condition) (c'mon, people, a * isn't always a pointer:-). Well, DRQ* requests an interrupt, the firmware & CPU interrupt, it reads the serial chip's byte, and stashes it into some handy memory buffer. Then it returns from interrupt.
A problem can emerge if you're getting data very fast. Let's assume data has come in, serial chip got a byte ("#1" in this example), asserted DRQ*, we interrupted, the firmware grabs and stashes byte #1, and returns from interrupt. All well and good. But think what happens if another byte comes winging in while that first interrupt is still running. The serial chip now has byte #2 in it, so it again asserts the already-asserted DRQ* pin. The interrupt of the first byte completes. What happens?
You hang.
This is because it's the -edge- of DRQ*, physically going from 5V to 0V, that actually causes the CPU interrupt. On the second byte, DRQ* started at 0 and was set to 0. So DRQ* is (still) asserted, but there's no -edge- to tell the interrupt hardware/CPU that another byte is waiting. And now, of course, all the rest of the incoming data is also dropped.
See why it gets worse at higher speeds? The interrupt routine is fielding data more and more quickly, and typically doing circular I/O buffer calculations within the interrupt handler, and it must be fast and efficient, because fast input can push the interrupt handler to where a full new byte comes in before the interrupt finishes.
This is why it's a good idea to check DRQ* during the interrupt handler to see if another byte (#2) is already waiting (if so, just read it in, to clear the serial chip's DRQ*, and stash the byte in memory right then), or use "level triggering" for interrupts, not "edge triggering". Edge triggering definitely has good uses, but you need to watch out for this.
I hope this is helpful. It sure took me long enough to figure it out the first time. Now I take great care on stuff like this.
Good luck, let me know how it goes.
thanks,
Dave Small
I'm working on a service desk application that returns a variety of information on the local network of a PC.
What I want to do is take the ip address of the PC - say 10.20.30.1 / 24, and get just the network octets. 10.20.30 in this case. However, even if the network was something like 100.15.1 it would still need to work.
I'd then want to add on different device numbers. For instance, if all the switches in a network fall in the 230 - 235 range by policy, I'd want to be able to cycle through and ping those numbers looking for active switches.
Right now I'm only working with /24 networks.
So far I'm pulling the IP address of the PCs fine, but I'm a little lost on how to proceed.. Should I change the IP into a string and use some kind of regex method to strip the first three octets? That feels a little clunky.
I don't mind reading up on new methods, etc, I'm just looking to get pointed in the right direction, so to speak.
Just
var s = "10.20.30.1 / 24";
s = s.Substring(0, s.LastIndexOf(".")); //"10.20.30"
You should use the IPNetwork2 nuget package that parse ipnetworks.
https://www.nuget.org/packages/IPNetwork2/
https://github.com/lduchosal/ipnetwork
IPNetwork ipnetwork = IPNetwork.Parse("10.20.30.1/24");
Console.WriteLine("Network : {0}", ipnetwork.Network);
Output
Network : 10.20.30.0
Have fun !
Regex methods wont work unless the network addresses are at 8-bit multiples. For a network address of a.b.c.d/n, what you need to do is create a bit-mask with n-ones, and then bitwise-and it to the IP address you want to test.
So mask = 0xffffffff << (32-n) to get you the bitmask, and then IPAddress_as_uint && mask to get you the network portion.
This question already has answers here:
Method to determine if path string is local or remote machine
(7 answers)
Closed 8 years ago.
I need to tell if a user entered the local machine's name in a textbox. This turns out to be trickier than I originally thought.
string userInput = inputTextbox.Text.ToLower();
string machineName = Environment.MachineName.ToLower();
bool isLocal = userInput.Equals(machineName ) || // This is what we started with...
userInput.Equals(".") || // Then we added this...
userInput.Equals("localhost"); // And then we added this...
As you can see, it's gotten quite messy and unmaintainable. For example, the address 127.0.0.1 wasn't included. Our testing department keeps writing bugs every time they find a new name for home. We need to squash this bug once and for all.
Is there an easier way to do this?
There are many definition for this machine
All IP addresses in all adapters (wireless, vpn and dhcp are here to mess up further)
127.x.y.x addresses (good catch #Alexander, I did not know that)
Any references to these IP addresses in hosts file
computer name
computer fully qualified dns name
dns records that point to that machine (I use multiple dns records point to same machine for http hostname header)
. char (which is valid only for some cases, like SQL server)
Any long number which can be converted to IP addresses listed above. For example try this: ping 2130706433
And this is what I managed to find in two minutes. But this will cover %80 of your cases. Other %20 will still be included in "prohibited" list.
BTW, Tell your test crew to find as many as they can find in one shot. This should reduce bounces from QA.
You could do something like
List<String> localNames = new List<string>{Environment.MachineName.ToLower(), ".", "localhost"};
bool isLocal = localNames.Any(s=>s.Equals(userInput));
Then you just need to extend the list rather than adding additional conditions.
Although not ideal, it makes the updating of your code easier. You could put in code to look up the local IP of the machine as well and add that automatically to the list of strings.
Personally, I've not seen any other way of doing something like this for all possible scenarios.
I have this C# script on Unity to scan available serial ports to connect to Neurosky. However, this is a manual detection, this just works on computers whose Starting port of ThinkGear Connector is COM9.
void setupNeuro() {
tgHandleId = ThinkGear.TG_GetNewConnectionId();
tgConnectionStatus = ThinkGear.TG_Connect(tgHandleId,
"\\\\.\\COM9",
ThinkGear.BAUD_9600,
ThinkGear.STREAM_PACKETS);
}
How to edit this C# script to automatically detect a right port from COM1 to COMxx ?
This isn't a Unity problem as much as it is a C# one. The ThinkGear docs mention that users should implement port scanning, but I don't recall there being any implementation provided, although the suggestion of storing the previous port is provided.
Unfortunately, there are no truly elegant ways to implement this, but there are ways.
The best you can do is looping through the ports until you get one that doesn't timeout, but this means each check needs to take at least 2 seconds. And to make matters worse, the only method you have to get connected Serial Ports from .NET in Unity isn't guaranteed to be up to date either. This means you might end up enumerating over a ton of serial ports in a really slow manner.
To minimize search times you should search in this order:
Last port that was used (Store this in PlayerPrefs)
All ports returned by SerialPort.GetPortNames. There won't be many, but unfortunately, there's no guarantee they all exist, since, as the docs say, SerialPort.GetPortNames checks a registry value that is not always up to date.
Ports 0-10 if you haven't already checked them.
Ports 10 - 256, but see below. At this point you'll have to at least give the user a chance to enter the port themselves, or give them a warning about how long the next step will take.
I wouldn't recommend going this far (does up to 8 minutes of searching sound reasonable?). You'll already have spent up to 20 seconds scanning the first 10 ports. It might be worth it to
Show users how to find the right port themselves
Write a small external program for each platform that uses lower level methods to display the right port for the user to enter.
Access those lower level methods from a OS-specific library and access it from Unity to limit your search to valid ports. This is the choice I'd go with.
Checking a port goes something like this (the lambda is needed because of the use of a coroutine):
IEnumerable AttemptHeadsetConnection(int portNumber,Action<int,int> headsetConnectedCallback, Action attemptCompletedCallback)
{
var connectionString = string.Format("\\\\.\\COM{0}",portNumber);//That string literal should be elsewhere
return AttemptHeadsetConnection(connectionString, headsetConnectedCallback, attemptCompletedCallback);
}
IEnumerable AttemptHeadsetConnection(string connectionString,Action<int,int> headsetConnectedCallback,Action attemptCompletedCallback)
{
connectionID = ThinkGear.TG_GetNewConnectionId();
connectionStatus = ThinkGear.TG_Connect(connectionID ,
connectionString,
ThinkGear.BAUD_9600,
ThinkGear.STREAM_PACKETS);
if(connectStatus >= 0)
{
yield return new WaitForSeconds(2f); //Give the headset at least 2 seconds to respond with valid data
int receivedPackets = ThinkGear.TG_ReadPackets(handleID, -1);//Read all the packets with -1
if(receivedPackets > 0)
{
headsetConnectedCallback(connectionID,connectionStatus);
}
else
{
ThinkGear.TG_FreeConnection(handleID);
}
}
attemptCompletedCallback();
}
And use that with something like:
foreach(var serialPort in SerialPort.GetPortNames())
{
var connectionCoroutine = AttemptHeadsetConnection(serialPort,onFoundHeadset,onAttemptCompleted);
StartCoroutine(connectionCoroutine);
}
Note about the code: It's not elegant, and it might not even compile (although it doesn't do anything that's impossible). Take it as very convincing psuedo-code and use it as your base.
loop thru the known ports substituting the COM number into the connect string until you either run out of ports (nothing connected) or find one that is...