I searched around the internet a lot of hours but I couldn't find anything that matches my case.
I simply want to implement a Server/Client App with TCP or UDP where my Android App (Xamarin) acts as a server and my .NET application as Client. Since I have not much experience with app development and no experience with Xamarin, I was looking for an example. All I found was this:
http://www.codeproject.com/Articles/340714/Android-How-to-communicate-with-NET-application-vi
First of all this is the opposite way (Server on .NET and Client as App) and additionaly it is for Android Studio so it's hard for me to translate these things into Xamarin without errors.
Please can someone help and give me an example how to realize my issue?
Thank you!
On Xamarin.Android you can use all of the regular .Net socket classes:
Namespaces:
using System.Net;
using System.Net.Sockets;
Example:
IPHostEntry ipHostInfo = Dns.GetHostEntry (Dns.GetHostName ());
IPAddress ipAddress = ipHostInfo.AddressList [0];
IPEndPoint localEndPoint = new IPEndPoint (ipAddress, 11000);
System.Diagnostics.Debug.WriteLine(ipAddress.ToString());
// Create a TCP/IP socket.
Socket listener = new Socket (AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
AndroidManifest.xml Required Permissions are:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
The MSDN-based Asynchronous Server Socket example works as a cut/paste example with no changes.
i.e.
Using the MSDN code, you can call the static method, AsynchronousSocketListener.StartListening, in a thread to start listening on port 11000 defined in the AsynchronousSocketListener class.
new Thread (new ThreadStart (delegate {
AsynchronousSocketListener.StartListening();
})).Start ();
Once it is running on your device/emulator, you can telnet into your Android TCP socket server:
>telnet 10.71.34.100 11000
Trying 10.71.34.100...
Connected to 10.71.34.100.
Escape character is '^]'.
Once connected, type in This is a test<EOF> and the Android will echo it back:
This is a test<EOF>
You do this like in normal .net, except you have to ask permissions to use sockets.
There are tons of simple example of creating a listening tcp connection in c#.
The problem you will have is to know the IP address of your server (in the phone) as it will likely change often when the user is moving.
Related
I have a question about C# communication.
Currently using .Net and studying Socket. You can create a socket server using the internal IP and connect as an internal client. Is it possible to open a server in another network like a chat program and connect to Socket Ip:Port from another network?
Socket sListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.20"), 8000);
sListener.Bind(ipEndPoint);
sListener.Listen(20);
Socket sClient = sListener.Accept();
Is there anything I need to configure to open the server using the above IP and port number and connect to the server from another network (Client)?
Thank you :]
Yes of course. I draw a little image for a normal connection over the internet.
What you have to do?
Open a port in your router (aka enable port-forward) and forward 60800 to 192.168.0.20:8000.
Determine your external ip. Google for "what is my ip" or go to my site.
Connect the via your-external-ip:60800.
Hint: 60800 can be any other random port-value. I suggest high random numbers, so that hacker/scanner can't discover your service so fast.
That is very basic. I recommend, that you start learn how the ip-communication is working.
I am struggling with a bit of network magic and hoped someone would be able to explain me what is happening.
I am trying to reuse udp ports. So if I have multible programs listening on the same udp port i want both of the applications to receive the data send by a different device.
Using the following code I'am able to achive just that:
IPEndPoint localEndoint = new IPEndPoint(IPAddress.Any, 67); //the local endpoint used to listen to port 67
//Create a new UDP Client and bind it to port 67
DhcpSniffer = new UdpClient();
DhcpSniffer.ExclusiveAddressUse = false; //Allow multible clients to connect to the same socket
DhcpSniffer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); // Connect even if socket/port is in use
DhcpSniffer.Client.Bind(localEndoint);
DhcpSniffer.Client.ReceiveTimeout = Timeout;
//receive on port 67
dhcpPacket = DhcpSniffer.Receive(ref localEndoint);
Both of my programs can listen to DHCP messages in the network and don't block each other.
Now i want to do the same thing with port 15120 where a RTP video stream is streamed to. However this does not work. I am using the same code but with no success only one application at a time can receive the stream, the other will run in a timeout.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, port);
//Create a new UDP Client and bind it to port 15120
udpReceiver = new UdpClient();
udpReceiver.ExclusiveAddressUse = false; //this is an attempt to receive the stream on mutlible instances...this works for DHCP but not for RTP for some reason....
udpReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); // Connect even if socket/port is in use
udpReceiver.Client.ReceiveTimeout = timeout; //set the sockete timeout
udpReceiver.Client.Bind(RemoteIpEndPoint); //bind to the port from any IP
//receive packets on port 15120
Byte[] receiveBytes = udpReceiver.Receive(ref RemoteIpEndPoint);
I hope somebody is able to shine a light on my confusion
Update:
I found out it works with DHCP because it is send to the broadcast IP (255.255.255.255). Now I need to find out how i can change the Socket behaviour to treat my RTP stream as if it was broadcasted so i can see it in two application at the same time. (Yes I could configure my stream-source to broadcast, but this is not the goal of this).
The goal is to reconfigure the Socket to behave as explained. Not to save the stream on a harddrive or redirect it using the local host.
First, its not possible to have multiple programs listen on the same port (As far as I know it's a big security conflict)
What you can do tough, is use a NetworkManager that listen on you port (Lets call it port 8080) who will then redirect the information to you apps ports (App1 could use port 8081 and App2 use port 8082). Either you write your own, using Flask to listen on 8080 and then rerouting the package to localhost:8081 and localhost:8082 could be a simple and fast solution.
Doing this would help you secure the network and you can redirect to as many ports as you need, pretty much like a docker swarm would balance the incoming network to its cluster.
It is not possible with multible programs to access the data from a unicast UDP package, it works only with multicast, there is no "easy" way around this by reconfiguring the UdpClient
I'm using Socket with following configuration to receive multicast packets and the code is working properly.
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(bindPoint);
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(multicastAddress, IPAddress.Any));
socket.ReceiveTimeout = 1000;
But after disabling the network connection from Control Panel and enabling, the socket cannot receive the multicast data. I can see the packets with Wireshark. I tried closing the socket, resetting he socket but restarting is the only solution I came up with. The application will be used in an environment where the user typically remove the ethernet cable and plug another one.
Initially I was using UdpClient but the same problem persists on that too. The operating system is Windows 7 and I use .NET 4.5.2.
After disabling a network connection, Windows automatically uses another connection if you have one (virtual host etc.). After enabling the previous connection, the application doesn't use the correct connection since there were no interface selection made. Disabling other connections or specifying the interface solves the problem.
I currently have 2 .Net applications which run on the same PC simultaneously.
These 2 applications communicate using UDP like this:
Client:
udpUnityToConsole = new UdpClient();
udpUnityToConsole.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
try
{
udpUnityToConsole.Connect("localhost", 11004);
}
Server:
unityUdpReceive = new UdpClient();
unityUdpReceive.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
unityUdpReceive.Client.Bind(new IPEndPoint(IPAddress.Any, 11004));
The communication stream is fast and reliable, there is just one issue with it and that is that if the PC is not connected to a network then it will crash with a
System.Net.Sockets.SocketException: No such host is known.
If the connection has been established already and then the PC is disconnected from the network, the connection will remain. Only if there is no network connection to start with will it fail.
Any suggestions are greatly appreciated.
All I had to do was change localhost to 127.0.0.1 which is the address of the local machine and never changes, therefore it is safe to use. Using localhost meant that the UDP library had to look up the IP being used with the localhost alias, but that wasn't necessary as I knew it already. I could probably also find out the IP some other way and run that query on both applications.
I've to implement some discovery for an internal solution.
We have two kind of software:
Server: They manage a lot of hardware devices and can give access to some data (.Net remoting)
Client: They can display data of one or several Server(graphs, stats, ...)
Currently we are setting the IP by hand on the client.
We would like to implement a discovery.
We have the following requirement:
It has to be usable in c#
When a server is up, it must be displayed as available very fastly
Same when it shut down
If the server doesn't stops in a clean way, we can have a way to detect it(no need to be very fast, can be done every 10-15min).
It can give me some information(Server version, port to use, ...)
We have client computer with multiple network cards, we must discover server on each cards
Do you have a protocol, a library, ... to advice?
We tried UPnP, but seems there is no good Server+client implementation in c# that meet our requirement
Use UDP broadcasts from the discovering app (client):
int broadcastPort = //something
byte[] msg = //something
//Cycle this for all IP adresses
IPAddress broadcastIp = //Broadcast address for this net
IPEndPoint destinationEndpoint = new IPEndPoint(broadcastIp, broadcastPort);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
sock.SendTo(msg, broadcastEndpoint);
And have the discovered app (Server) answer, to receive the answer use UdpClient.Receive(), which gives you the IP of the answering station.