UDP Client - Reception of enqueued packets - c#

I am developing a UDP Client PC application. It is supposed to receive UDP datagrams from more than 4 devices.
The system behaves in the following way:
Multiple devices are communicating with each other via UDP broadcasts on a fixed port (11000) forming a personal area network with no connectivity to the internet.
PC application is executed on a computer connected to the same network.
PC application listens to UDP broadcasts on 11000 port to discover the devices.
When a specific command is received from the PC application, that device goes into a different execution mode while other devices continue to broadcast their packets.
This behaves in the desired manner when there is only one device in the personal area network.
I am facing a strange issue when there are two or more devices in the network, such that:
I set the endPoint to the desired IPAddress and Port of the desired device using the discovered device list.
I call myUDP.Receive(ref endPoint); to receive UDP Datagram
This returns with the Datagram which was broadcasted by the second device in the network, rather than returning the response from the device with which I am trying to communicate. I have verified using the Wireshark that the response is sent from the device.
I tried looping through for a finite number of times to get the desired datagram.
// Some code which initializes the endPoint with desired IP Address and Port
...
// Some code which sends the data
...
// Some code which sets the IP Address of the device from which the response is expected
selectedIPAddress = IPAddress.Parse(labelIPAddressSettings.Text.Trim());
copyendPoint = endPoint;
// Listen to response
do
{
rexdDatagram = myUDP.Receive(ref endPoint);
if (endPoint.Address != selectedIPAddress)
{
// This datagram is not from the desired device
// Restore to the desired endpoint
endPoint = copyendPoint;
// Not sure if there is way to discard this enqueued datagram
}
i_timeout = i_timeout + 1;
if (i_timeout == 10)
{
// Datagram from the desired device has not been received
break;
}
// Not sure if the thread needs to sleep, debugging..
Thread.Sleep(1000);
} while (1);
Question:
Is my code correct to loop within enqueued datagrams? Is there a way to discard previous datagrams and start afresh?

The parameter remoteEP on the method UdpClient.Receive is not meant for specifying from which remote endpoint to receive from, but rather to specify which remote endpoint sent the data. You cannot selectively receive only from a specific endpoint.
Instead, you'll have to receive everything from everyone, and discard the packages that were not sent from your desired remote endpoint. You can do this like so:
byte[] receivedData = null;
var attempts = 0;
while (attempts < 10)
{
var recvEp = new IPEndPoint(IPAddress.Any, 0);
readData = myUDP.Receive(ref recvEp);
if (recvEp.Address == selectedIPAddress)
{
// We received data from the correct remote source
receivedData = readData;
break;
}
attempts++;
}
This code will receive data from anywhere, and if it doesn't receive data from the correct endpoint within 10 attempts, it will stop. Resulting in receivedData being null.
You might want to convert your code to wait for a certain amount of time not a certain amount of attempts, to increase the chances of actually receiving something. This could be done like so:
var start = DateTime.Now;
byte[] receivedData = null;
while((DateTime.Now - start).TotalSeconds < 10)
{
var recvEp = new IPEndPoint(IPAddress.Any, 0);
readData = myUDP.Receive(ref recvEp);
if (recvEp.Address == selectedIPAddress)
{
// We received data from the correct remote source
receivedData = readData;
break;
}
}
This code will try for 10 seconds, and stop after 10 seconds if nothing was received. This is not perfectly clean code, for example if you want to you can make this whole thing async.
Note: It is possible that both code snippets will result in an infinite loop, as myUDP.Receive(ref recvEp) will block as long as there isn't any incoming data. So if all your remote endpoints decide to stop sending data at the same time, the receive call will never return

Related

Modbus communication over tcp doesn't send data to all devices

I have a gateway connected to a computer which runs a C# program. I have a Modbus slave-master relation between computer and the gateway. Here are the gateway configurations (model EKI-1221-BE):
The set up I have is the same as in this picture but I have 6 devices connected instead of 2 and will later have 12:
I can send a Modbus command to any of the 6 devices without any problems but the issue happens when I try to send multiple commands in quick interval. In the following code, only the device 1,2 and 6 receive the command.
PumpsComm.SendMessage(1, 3099, 2000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(2, 3099, 3000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(3, 3099, 4000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(4, 3099, 6000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(5, 3099, 8000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(6, 3099, 10000);
PumpsComm.ClientSocket.Receive(TempBuffer);
The function SendMessage is as follows, where ClientSocket is a TCP Socket that is connected to the gateway / Modbus slave.
public void SendMessage(int pumpID, int register, int command)
{
byte[] message = new byte[12];
message[0] = 0;
message[1] = 0; //Message number
message[2] = 0;
message[3] = 0;
message[4] = 0;
message[5] = 6; //Message length
message[6] = (byte)ToHexInDec(pumpID, 'L'); //Pump ID
message[7] = 6;
message[8] = (byte)ToHexInDec(register, 'H'); //Register high
message[9] = (byte)ToHexInDec(register, 'L'); //Register low
message[10] = (byte)ToHexInDec(command, 'H'); //Command high
message[11] = (byte)ToHexInDec(command, 'L'); //Command low
try
{
ClientSocket.Send(message);
}
catch
{
return;
}
}
If I make the Thread sleep for 30ms between each send, every command works but this is not an option in my case as I need to be able to update every device in a very short amount of time.
I looked at the packets that I was sending and receiving to and from the gateway with Wireshark and I think I found where the
This is what the output of Wireshark was (the Ip that ends with 200 is the computer and the one that ends with 107 is the gateway):
It looks as though the communication for the device 3,4,5 and 6 where put in the same TCP packet and for some reason, the only Modbus communication that was read from that packet is the last one.
I tried adding MBAP transaction numbers for every communication in the MBAP header of the Modbus communication but it didn't change anything. I then tried to add a blocking receive that makes the program wait for the Modbus response before sending the next communication but I am not receiving anything (even though we can see that the gateway is sending a Modbus response back when the communication was successfull)
I don't know what I can do anymore and was looking to see if anyone with more experience with TCP modbus communications could help. I can provide more details if necessary. Sorry if this is not clear enough, english is not my first language.
Thanks!
As per the spec
Several MODBUS transactions can be activated simultaneously on the same TCP
Connection.
Remark: If this is done then the MODBUS transaction identifier must be used to
uniquely identify the matching requests and responses
However you are sending messages with the transaction identifier set to 0000:
message[0] = 0;
message[1] = 0; //Message number
(I'm guessing that the gateway is detecting the duplication and assigning a new identifier because of this).
A better approach would be to send all of your requests (each with a different identifier; it does not matter what this is as long as it's unique) and then wait for the responses to come in (matching the response to the request using the transaction identifier in each response; responses may be in a different order to the requests).
Note that you should not assume that each response will come in a separate TCP packet (or that it will be in a single packet); the protocol takes this into account:
When MODBUS is carried over TCP, additional length information is
carried in the MBAP header to allow the recipient to recognize message
boundaries even if the message has been split into multiple packets for
transmission. The existence of explicit and implicit length rules, and use of a CRC-32 error check code (on Ethernet) results in an infinitesimal chance of undetected corruption to a request or response message.

Listen to responses from 2 TcpClient instances against the same IP, but different ports

I'm working on a TCP connection where my client connects to a server's IP on 2 different ports. So I have 2 instances of TcpClient objects, one connecting to the IP on port 9000 and the other on port 9001.
The aim of 2 connections is that the server uses the active connection on port 9000 to give certain responses to the client frequently, and the client uses these responses to form and send a request on port 9001.
Now, the first time I connect on 9000, I get a response, I then form a request and fire off via 9001. Now I have a feeling I'm doing something wrong with the way I'm managing asynchronous requests to both ports, but I can't figure an alternate way of doing this:
IPAddress IPAddress = IPAddress.Parse("192.168.1.10");
public static async Task ConnectToPort9000()
{
TcpClient TcpClient1 = new TcpClient();
try
{
await TcpClient1.ConnectAsync(IPAddress, 9000);
if (TcpClient1.Connected)
{
byte[] Buffer = new byte[1024];
while (await TcpClient1.GetStream().ReadAsync(Buffer, 0, Buffer.Length) > 0)
{
//Server returns a message on this port
string Port9000Response = Encoding.UTF8.GetString(Buffer, 0, Buffer.Length);
//Setting ConfigureAwait(false) so that any further responses returned
//on this port can be dealt with
await Task.Run(async () =>
{
await SendRequestToPort9001BasedOnResponseAsync(Port9000Response);
}).ConfigureAwait(false);
}
}
}
catch (Exception)
{
throw;
}
}
private async Task SendRequestToPort9001BasedOnResponseAsync(string Port9000Response)
{
//Open connection on port 9001 and send request
TcpClient TcpClient2 = new TcpClient();
await TcpClient2.ConnectAsync(IPAddress, 9001);
if (TcpClient2.Connected)
{
//Handle each string response differently
if (Port9000Response == "X")
{
//Form a new request message to send on port 9001
string _NewRequestMesssage = "Y";
byte[] RequestData = Encoding.UTF8.GetBytes(_NewRequestMesssage);
new SocketAsyncEventArgs().SetBuffer(RequestData, 0, RequestData.Length);
await TcpClient2.GetStream().WriteAsync(RequestData, 0, RequestData.Length);
await TcpClient2.GetStream().FlushAsync();
//Handle any responses on this port
//At this point, based on the request message sent on this port 9001
//server sends another response on **port 9000** that needs separately dealing with
//so the while condition in the previous method should receive a response and continue handling that response again
}
else if (Port9000Response == "A")
{
//Do something else
}
}
}
The issue I am having at the moment is, after I send the request on port 9001, when processing any response messages on port 9001, the server has already sent me a response on port 9000, but my while loop on the first method isn't getting triggered, and it seems like that's because it's still executing the second method to process request/response on port 9001. I tried using ConfigureAwait(false) to basically fire and forget, but it doesn't seem to be working. Am I handling asynchronous processes the wrong way? Or should I look at alternatives such as action/delegates?
The aim of 2 connections is that the server uses the active connection on port 9000 to give certain responses to the client frequently, and the client uses these responses to form and send a request on port 9001.
Please don't do this. Socket programming is hard enough without making it extremely more complicated with multiple connections. Error handling becomes harder, detection of half-open connections becomes harder (or impossible), and communication deadlocks are harder to avoid.
Each socket connection is already bidirectional; it already has two independent streams. The only thing you need to do is always be reading, and send as necessary. The read and write streams are independent, so keep your reads and writes independent.

TCP server only accepts the message from one iOS device at a time

I use c# to create a TCP server to connect to the iOS devices. However, I've found that it can only accept one iOS device at a time. I couldn't figure out what is the problem. Can anyone have a look and see what is the problem?
IPAddress ipadr = IPAddress.Parse(localIP);
System.Net.IPEndPoint EndPoint = new System.Net.IPEndPoint(ipadr, 8060);
newsock.Bind(EndPoint);
newsock.Listen(10);
client = newsock.Accept();
IPEndPoint clientip = (IPEndPoint)client.RemoteEndPoint;
while (true)
{
if (!isDisConnected)
{
data = new byte[1024];
recv = client.Receive(data);
if (recv == 0)
break;
string receivedText = Encoding.ASCII.GetString(data, 0, recv);
}
client.Close();
newsock.Close();
There are two kinds of sockets: The socket that you use to listen (it is never connected) and the sockets that correspond to connections (each socket represents one connection).
Accept returns you a connected socket to the client that was just accepted. Each call to Accept accepts a new, independent client.
If you want to handle more than one client at a time (which is almost always required) you must ensure that a call to Accept is pending at all times so that new clients can be accepted.
A simple model to achieve this is to accept in a loop forever and start a thread for each client that you accepted:
while (true) {
var clientSocket = listeningSocket.Accept();
Task.Factory.StartNew(() => HandleClient(clientSocket));
}
Take a look at AcceptAsync. Each accept operation allows one connection, so you have to call Accept again. AcceptAsync works asychronously and avoids the difficulties of having to create delegates or threads.
The general model is:
Accept operation completes
Hand off AcceptSocket to code that will Receive data asychronously from that socket.
Call Accept again to listen for more clients.
The same principle also works if you want to do synchronous receives.
Check out this question: Server design using SocketAsyncEventArgs

TCP socket.receive() seems to drop packets

I am working on client-server appliction in C#. The comunication between them is with TCP sockets. The server listen on specific port for income clients connection. After a new client arrived, his socket being saved in a socket list. I define every new client socket with receive timeout of 1 ms. To receive from the client sockets without blocking my server I use the threadpool like this:
private void CheckForData(object clientSocket)
{
Socket client = (Socket)clientSocket;
byte[] data = new byte[client.ReceiveBufferSize];
try
{
int dataLength = client.Receive(data);
if (dataLength == 0)// means client disconnected
{
throw (new SocketException(10054));
}
else if (DataReceivedEvent != null)
{
string RemoteIP = ((IPEndPoint)client.RemoteEndPoint).Address.ToString();
int RemotePort = ((IPEndPoint)client.RemoteEndPoint).Port;
Console.WriteLine("SERVER GOT NEW MSG!");
DataReceivedEvent(data, new IPEndPoint(IPAddress.Parse(RemoteIP), RemotePort));
}
ThreadPool.QueueUserWorkItem(new WaitCallback(CheckForData), client);
}
catch (SocketException e)
{
if (e.ErrorCode == 10060)//recieve timeout
{
ThreadPool.QueueUserWorkItem(new WaitCallback(CheckForData), client);
}
else if(e.ErrorCode==10054)//client disconnected
{
if (ConnectionLostEvent != null)
{
ConnectionLostEvent(((IPEndPoint)client.RemoteEndPoint).Address.ToString());
DisconnectClient(((IPEndPoint)client.RemoteEndPoint).Address.ToString());
Console.WriteLine("client forcibly disconected");
}
}
}
}
My problem is when sometimes the client send 2 messages one after another, the server doesn't receive the second message. I checked with wireshark and it shows that both of the messages were received and also got ACK.
I can force this problem to occur when I am putting break point here:
if (e.ErrorCode == 10060)//recieve timeout
{
ThreadPool.QueueUserWorkItem(new WaitCallback(CheckForData), client);
}
Then send the two messages from the client, then releasing the breakpoint.
Does anyone met this problem before?
my problem is when sometimes the client send 2 messages one after another, the server doesn't receive the second message
I think it's much more likely that it does receive the second message, but in a single Receive call.
Don't forget that TCP is a stream protocol - just because the data is broken into packets at a lower level doesn't mean that one "send" corresponds to one "receive". (Multiple packets may be sent due to a single Send call, or multiple Send calls may be coalesced into a single packet, etc.)
It's generally easier to use something like TcpClient and treat its NetworkStream as a stream. If you want to layer "messages" on top of TCP, you need to do so yourself - for example, prefixing each message with its size in bytes, so that you know when you've finished receiving one message and can start on the next. If you want to handle this asynchronously, I'd suggest sing C# 5 and async/await if you possibly can. It'll be simpler than dealing with the thread pool explicitly.
Message framing is what you need to do. Here: http://blog.stephencleary.com/2009/04/message-framing.html
if you are new to socket programming, I recommend reading these FAQs http://blog.stephencleary.com/2009/04/tcpip-net-sockets-faq.html

Find server listening on a specific port on local network

I have a server application. I also have a client application. I am able to establish a tcp connection between the applications when both applications happen to be on the same network. so let's say that the computer running the server application is listening from new connections on port 2121 and it has the LAN ip address 192.168.0.120. On a different computer running the client application I will be able to establish a connection by providing port number 2121 and ip address 192.168.0.120.
Is there a way to find all computers on a network that are listening on port 2121?
One algorithm that I am thinking now is like:
get ip address of current computer and lets say it comes out as 192.168.0.145.
now most likely the server will be listening on ip addresss 192.168.0.?
then ping 192.168.0.1 on port 2121 then 192.168.0.2 on port 2121 ... and then keep going.
I don't know if that method is efficient. moreover there might be a possibility that the server happens to be listening on ip address 192.168.1.x
So what changes will I have to make to my server and client application so that the client is able to find all the servers listening on port 2121?
The algorithm you proposed is the one you need. One problem is in the dynamic generation of the candidate IP addresses.
Normally, the possible IP address range is the one given by the subnet mask ( http://en.wikipedia.org/wiki/Subnetwork ). More exactly, the part of the IP that change is that part when in the subnet mask you have 0bits (always at the end of mask).
In your example:
if the mask is 255.255.255.0, then your possible ip address range is
192.168.0.*.
if the IP can also be 192.168.1.* then probably the mask should be 255.255.0.0
you can also have mask like 255.255.255.128 and the range would be 192.18.1.[1-126]. You can practically learn more using http://www.subnet-calculator.com/
The only other possibilities which cause your problem that I see to have these distinct ranges are:
you have more DHCP servers in your network, which is really bad as you will have "race conditions". The solution here is to fix your infrastructure by removing all but 1 DHCP server
you have manually set IP addresses (probably on laptops). The solution is to change to DHCP (if you need a specific IP that will always be assigned to a specific computer, use static DHCP)
Getting back to the problem of finding the problem of checking if "something" is listening on a specific port, the ICMP protocol is not the best here, as the majority of firewalls filter both the broadcast ICMP and single ICMP. If we are truly talking of a server, chances are you had to manually open the port you are looking for. Also, even if all computers respond, you still don't know if they host your wanted service.
The solution below involves computing the possible range of candidate IP addresses. After that you iterate through them to see if you can connect to your port.
In this implementation I test sequentially, which proves to be very slow as the timeout for connect is 30 seconds if the host is not on. For several hundred candidates, it doesn't sound too good. However, if the majority of host are available (even if they don't host your service), everything will go several times faster.
You can improve the program by either finding out how to decrease this timeout (I couldn't find out how in my allocated time) or to use a custom timeout as presented in How to configure socket connect timeout . You could also use multi-threading and adding the address that worked in a thread-safe collection and work with it from there.
Also, you could try pinging (ICMP) before, but you could miss valid servers.
static void Main(string[] args)
{
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
int wantedPort = 21; //this is the port you want
byte[] msg = Encoding.ASCII.GetBytes("type msg here");
foreach (NetworkInterface netwIntrf in NetworkInterface.GetAllNetworkInterfaces())
{
Console.WriteLine("Interface name: " + netwIntrf.Name);
Console.WriteLine("Inteface working: {0}", netwIntrf.OperationalStatus == OperationalStatus.Up);
//if the current interface doesn't have an IP, skip it
if (! (netwIntrf.GetIPProperties().GatewayAddresses.Count > 0))
{
break;
}
//Console.WriteLine("IP Address(es):");
//get current IP Address(es)
foreach (UnicastIPAddressInformation uniIpInfo in netwIntrf.GetIPProperties().UnicastAddresses)
{
//get the subnet mask and the IP address as bytes
byte[] subnetMask = uniIpInfo.IPv4Mask.GetAddressBytes();
byte[] ipAddr = uniIpInfo.Address.GetAddressBytes();
// we reverse the byte-array if we are dealing with littl endian.
if (BitConverter.IsLittleEndian)
{
Array.Reverse(subnetMask);
Array.Reverse(ipAddr);
}
//we convert the subnet mask as uint (just for didactic purposes (to check everything is ok now and next - use thecalculator in programmer mode)
uint maskAsInt = BitConverter.ToUInt32(subnetMask, 0);
//Console.WriteLine("\t subnet={0}", Convert.ToString(maskAsInt, 2));
//we convert the ip addres as uint (just for didactic purposes (to check everything is ok now and next - use thecalculator in programmer mode)
uint ipAsInt = BitConverter.ToUInt32(ipAddr, 0);
//Console.WriteLine("\t ip={0}", Convert.ToString(ipAsInt, 2));
//we negate the subnet to determine the maximum number of host possible in this subnet
uint validHostsEndingMax = ~BitConverter.ToUInt32(subnetMask, 0);
//Console.WriteLine("\t !subnet={0}", Convert.ToString(validHostsEndingMax, 2));
//we convert the start of the ip addres as uint (the part that is fixed wrt the subnet mask - from here we calculate each new address by incrementing with 1 and converting to byte[] afterwards
uint validHostsStart = BitConverter.ToUInt32(ipAddr, 0) & BitConverter.ToUInt32(subnetMask, 0);
//Console.WriteLine("\t IP & subnet={0}", Convert.ToString(validHostsStart, 2));
//we increment the startIp to the number of maximum valid hosts in this subnet and for each we check the intended port (refactoring needed)
for (uint i = 1; i <= validHostsEndingMax; i++)
{
uint host = validHostsStart + i;
//byte[] hostAsBytes = BitConverter.GetBytes(host);
byte[] hostBytes = BitConverter.GetBytes(host);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(hostBytes);
}
//this is the candidate IP address in "readable format"
String ipCandidate = Convert.ToString(hostBytes[0]) + "." + Convert.ToString(hostBytes[1]) + "." + Convert.ToString(hostBytes[2]) + "." + Convert.ToString(hostBytes[3]);
Console.WriteLine("Trying: " + ipCandidate);
try
{
//try to connect
sock.Connect(ipCandidate, wantedPort);
if (sock.Connected == true) // if succesful => something is listening on this port
{
Console.WriteLine("\tIt worked at " + ipCandidate);
sock.Close();
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
//else -. goes to exception
}
catch (SocketException ex)
{
//TODO: if you want, do smth here
Console.WriteLine("\tDIDN'T work at " + ipCandidate);
}
}
}
Console.ReadLine();
}
sock.Close();
}
(sorry for my bad english) I am actually needing something similar to this and just found out about multicast. Here you can find an article and example. The sample app from the article worked fine on my lan. I do not know exactly how it works but maybe you can multicast something from the client and have the server(s) to respond with its IP? Or if that do not work, have the server multicasting his IP in a timed interval should do it. Sorry for the lack of informations, i just learned about this :)
An option i am not seeing beeing discussed here is to have a Master Server.
The idea is quite simple: A server where your application's server can register and where you application clients can get a list of active servers.
Server A is loaded and imediatly sends a hello message to the Master Server
Server B is loaded and sends an hello message to the Master Server
Both Server A and B keep sending hello's to Master Server every X Minutes so he knows they are still on
Client A is loaded - Needs to issue command - asks Master Server for List of Active Servers - Picks a server from the list - issues command
Things to keep in mind:
Master Server must be on a known address / port - either fixed ip or get ip throw well known ServerName
Purpose of Master Server is simply register servers and supply clients with their addresses - At first glance i see no other service it could provide your application
If any server is as good as any other for your application, i would advise the list to be ordered according to timestamp of last hello message received from that server - that way client will have at the top of that list the server most likelly to still be up (since it reported beeing up last) and can go down the list subsequentially.
More over, every time the Master Server receives an hello that list changes, so every so often client requests will get a different server list and use a different preferencial server, relieving load on servers accross the board.
can't you use the same method as when you get your ip.
let the client send a broadcast - if no response wait
server receive broadcast and send one back with its own ip.
now the client know that the server is out there and on what ip.
I assume you have a single server. If you can guarantee that the server location (ip address and port) is constant (or can be looked up) then each client application can 'register' with the server by connecting to it and informing the server about the ip address and local port to call back.
ICMP Ping does not determine if a computer is listening on a specific port, only if the computer is configured to response to a ping. ICMP is a protocol, different then TCP or UDP. It's only use for you would be to determine if an IP Address is use, and even then is becoming less viable.
You have two options.
Have the client constantly check every IP address on your local network and try to open port 2121. This is not a good option.
Have every server send out a ICMP ping to the broadcast address with specific data announcing it is on (and optionally not connected to a client) the never every so often (I would recommend a minute for testing, and 5 minutes minimum for production). All your software has to do is look for the broadcast ping and connect to the sending IP Address.
Update:
using System.Net.NetworkInformation;
private Ping _Ping = new Ping();
private PingOptions _PingOptions = new PingOptions(64, true);
private byte[] _PingID = Encoding.ASCII.GetBytes("MyPingID");
private _PingResponse = new AutoResetEvent(false);
public <classname> //Constructor
{
_Ping.PingCompleted += new PingCompletedEventHander(PingCompleted);
}
public void PingCompleted(object Sender, PingCompletedEventArgs e)
{
if (e.Cancelled)
{
//Status Unknown;
}
else if (e.Error != null)
{
//Status Error;
}
else if (e.Reply.Status == IPStatus.Success)
{
// Device Replying
}
else
{
// Status Unknown
}
}
public void StartPing(string AddressToPing)
{
IPAddress ipAddress = IPAddress.Parse(AddressToPing);
_Ping.SendAsync(ipAddress, 15000, _PingID, _PingOptions, _PingResponse);
}
you can make the server send his location to a specific port using UDP, and the client listen to it then the client establish a connection with the server based on the given ip and port.

Categories

Resources