Socket communication for inter-WebRole communications in Azure - c#

I'm trying to make a simple client-server in Azure. I have the client in one webrole and the server in another, and both belong to the same tenant.
I want to use simple socket communication between the two to send a dummy file from client to server.
Here is how I wrote my app (some code removed for clarity):
1- Define "internal" tcp endpoints for each role. Assume server's port is 9000. Client's port is 9010.
2- The client sends a dummy file to the server as follows:
byte[] buffer = File.ReadAllBytes(filePath);
mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
mSocket.Connect(IPAddress.Parse(serverIPString), 9000);
mSocket.Send(buffer);
3- On the server, I do the following:
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 9000);
mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
mSocket.Bind(ipEnd);
mSocket.Listen(BACKLOG);
Socket socket = mSocket.Accept();
byte[] buffer = new byte[BUFFER_SIZE];
int byteCount = socket.Receive(buffer);
Everything works fine locally in the Azure emulator, but when I go to the cloud the server doesn't get any connections :(
Please help!
Addendum:
Someone asked how I find my endpoints.
I display my endpoints on the main page of the server as follows and let the sender/client specify the IP they want to send the file to in a textbox.
foreach (var instance in RoleEnvironment.CurrentRoleInstance.Role.Instances)
foreach (KeyValuePair<string, RoleInstanceEndpoint> pair in instance.InstanceEndpoints)
addresses += "[" + pair.Key + "] " + pair.Value.IPEndpoint.Address + ":" + pair.Value.IPEndpoint.Port + ", ";

This might be a network/IP issue like a firewall or the code not recognizing the IPs and not letting communication through.

Your server needs to be in a loop waiting for a connection. I'm not sure if you just summarized that out for your sample code, or if that is what is missing. Your use of the Socket interface looks correct as far as the order in which you are invoking its operations.
Hope this helps http://msdn.microsoft.com/en-us/library/6y0e13d3.aspx
Addendum: Nevermind, just noticed Socket.Accept() suspends so shouldn't have the problem I was thinking of when I looked at it.

Related

Cannot send data over UDP in UWP

I am trying to send the data over UDP in UWP Application. However, I cannot see the data being sent on Wireshark.
Just to check if firewall is causing any issue, I disabled it and tried sending the data again. However, I still don't see the data on Wireshark. Here's my code:
UdpClient client = new UdpClient();
client.EnableBroadcast = true;
client.Connect(IPAddress.Broadcast, 9520);
Byte[] senddata = Encoding.ASCII.GetBytes("Hello!");
client.Send(senddata, senddata.Length);
client.Close();
Am I missing something obvious here? I am using Visual Studio 2017 to build this UWP Application.
This page explains why the above code will not work if the App capabilities were not configured.
I didn't configure the capabilities before asking this question. However, I came across the page and enabled some capabilities (Internet(Client & Server), Internet(Client), Private Networks(Client & Server)).
After configuring them, my earlier code is working fine.
If you're facing the same problem, please configure the capabilities by going to Package.appxmanifest -> Capabilities and then rebuild the solution. After correctly enabling the capabilities, your app shall send the data. :) :)
You can use codes below I write and test it, it works fine
byte[] package= Encoding.ASCII.GetBytes(udpInfo[2].ToString());
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(udpInfo[0].ToString()), Convert.ToInt32(udpInfo[1]));
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
try
{
sock.SendTo(package, ep); //send packet to sw ip
Console.WriteLine("package sent");
return true;
}
catch (Exception ex)
{
Console.WriteLine("package can't sent");
return false;
}
EDIT: udpInfo arraylist declaration below:
public ArrayList udpInfo = new ArrayList(); // 0-ip 1-port 2-command
udpInfo[0] = "192.168.1.1"
udpInfo[1] = 1111
udpInfo[2] = "some commands"

Multiple Clients on TCPListener C# / Server sending Data [duplicate]

This question already has an answer here:
C# TcpClient: Send serialized objects using separators?
(1 answer)
Closed 4 years ago.
Being a "novice" in C# and C# Network programming I tried to make a simple chat in C# using TCPClient and TCPListener , I've managed to send data from client to server but if I add a second client the server doesnt read his data and i have a second issue I couldn't figure out how to send data from server to client using TCPListener .
Server :
while (true)
{
Socket client = Server.AcceptSocket();
Console.WriteLine("Connection accepted from " + client.RemoteEndPoint);
count += 1;
string msg;
byte[] buf = new byte[1024];
client.Receive(buf);
msg = Encoding.UTF8.GetString(buf);
Console.WriteLine("Received... " + msg + "");
}
}
Client :
while (true)
{
Console.WriteLine("Connected");
Console.Write("Enter the string to be transmitted : ");
String msg = Console.ReadLine();
Stream stm = tcpClient.GetStream();
ASCIIEncoding asen= new ASCIIEncoding();
byte[] send = asen.GetBytes(msg);
Console.WriteLine("Transmitting.....");
stm.Write(send, 0, send.Length);
if (msg == "/Q"){
tcpClient.Close();
Environment.Exit(0);
}
}
If you see any absurdity / Mistake in my code please tell me i'm here to learn !
Thank You
Where I am not the best with C# this post Server Client send/receive simple text how to create C# simple server, and should fix the first issue of the client not being able to recive data from the server.
As for the second issue not being able to support mulitple connections, this could be to do with there is no threading, so the question is do you want to create a C# webserver or a C# application which utilizes TCP communication to a server.
if the answer is the latter, then I would look to installing tried and tested server such a Apache or Nginx. this will allow the server to handle multiple requests on your behalf and skip having to handle multiple connections and threads, while you are learning more about the client server relationship. also this article may help setting up the fastcgi environment for the appliction http://www.mono-project.com/docs/web/fastcgi/nginx/
otherwise then you will have to look at how to handle multiple clients which this post looks like it could help TCP server with multiple Clients

How to use TCP Client in Android without Sockets?

I have a TCP server in C# and also a TCP Client in C#, now I need a TCP Client in Android too.
All the examples i found are related to sockets, but I'm using a simple TCP Client so they don't work.
Right now my C# TCP Client is like that:
TcpClient client = new TcpClient("127.0.0.1", 1200);
NetworkStream n = client.GetStream();
Console.WriteLine("Insert name");
string name= Console.ReadLine();
byte[] message = Encoding.Unicode.GetBytes(name);
n.Write(message, 0, message.Length);
Is there a corresponding of this function in Android?
This is the actual android client i'm trying and that doesn't work
InetAddress serverAddr = InetAddress.getByName("127.0.0.1");
socket = new Socket(serverAddr, 1200);
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
First, this line:
InetAddress serverAddr = InetAddress.getByName(127.0.0.1);
contains a syntax error. It should be:
InetAddress serverAddr = InetAddress.getByName("127.0.0.1");
Second, the address "127.0.0.1" refers to the "same machine" that executes the client. In the case of your C# program, the server runs on the same machine as the client, so it worked. But in the case of Android, there in no server that runs on the "same machine", which is your Android phone (event if it is emulated, 127.0.0.1 refers to the emulated Android device, not the PC that it works on). You must specify a "good" address to the Android device that refers to the machine on which the server executes.
So, the problem is not in using sockets.
You can simply connect to your server using this line, also try to disable your firewall if your server is running on your PC.
Socket server= new Socket("192.168.1.1", 4444); // Enter your PC/Server IP address in place of 192.168.1.1

Using specific network interface in C# with VLC ActiveX Plugin

I'm working now on the IPTV program in C#. As a media engine I'm using a VLC ActiveX Plugin. Data goes over UDP protocol.
Now I ran into the problem.
I have several networking interfaces. For example, I have Local Area Connection, that is used for network and Internet access, and VirtualBox Network.
First connection has an IP-address of 10.10.10.2 and second - 192.168.1.2.
When I trying to join multicast-group, some of IGMP-queries go through the VirtualBox Network instead of Local Area Connection. So I don't receive a multicast-traffic.
I need to choose specific interface (Local Area Network) for my application. So all data will going through this network interface.
I found some answers in the Internet, but not specifically for my problem.
Here's something, that I was trying to use:
IPAddress localAddress = IPAddress.Parse("10.10.10.2");
IPEndPoint localEndPoint = new IPEndPoint(localAddress, 0);
Socket client = new Socket(localEndPoint.AddressFamily, SocketType.Raw, ProtocolType.Igmp);
client.Bind(localEndPoint);
axVLCPlugin21.playlist.add("udp://#239.1.9.2:1234", axVLCPlugin21, null);
axVLCPlugin21.playlist.play();
But it's not working. Can someone help me, please?
Thank you!
I finally did it! I make a socket and bind it using my needed network interface. After that, I send IGMP-query using this socket and then receive data over needed network interface.
Now I'm using this code:
Socket mcastSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPAddress localAddress = IPAddress.Parse("10.10.10.2");
IPEndPoint localEndPoint = new IPEndPoint(localAddress, 0);
mcastSocket.Bind(localEndPoint);
IPAddress mcastAddress = IPAddress.Parse("239.1.9.2");
MulticastOption mcastOption = new MulticastOption(mcastAddress, localAddress);
mcastSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcastOption);
axVLCPlugin21.playlist.add("udp://#239.1.9.2:1234", axVLCPlugin21, null);
axVLCPlugin21.playlist.play();

Client sends a UDP Packet to a server over the internet, but it could not recieve any UDP packages from the server

Client sends a UDP Packet to a server over the internet, but it could not recieve any UDP packages from the server.
Server has a valid IP and I'm connected to the internet via ADSL
In both server and client these codes are used:
Send Packet:
Socket sock1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint iep1 = new IPEndPoint(IPAddress.Parse(txt_IP.Text), Convert.ToInt32(txt_SendPort.Text));
byte[] data = Encoding.ASCII.GetBytes("UDP");
sock1.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
sock1.SendTo(data, iep1);
Receive Packet:
Console.WriteLine("Listening to the port {0}", PortNumber);
sock1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, PortNumber);
sock1.Bind(iep);
EndPoint ep = (EndPoint)iep;
byte[] data1 = new byte[100];
int recv = sock1.ReceiveFrom(data1, ref ep);
sock1.Close();
String str_Data = Encoding.ASCII.GetString(data1, 0, recv);
String str_IP = ep.ToString().Substring(0, ep.ToString().IndexOf(":"));
Console.WriteLine("Received Succesfully: {0} - {1}", str_Data, str_IP);
My NIC IP is 169.254.254.5, But the server shows my IP is 188.136.170.14 and send the reply to 188.136.170.14 (188.136.170.14 is the IP of access point). How can I change the code in the server side to send bank the packet to the client correctly?
By access point, is that your router? You said ADSL, so I'll assume it is.
Your router spans 2 networks. The Internet is on 1 side in the form of your ISP & your internal network is on the other. This is why the server sees your router IP, not your NIC IP.
You need to define a port forward rule on the router to send inbound traffic on the port you're using onwards to your PC. Don't use broadcast either - this is for contacting a number of NICs on a subnet.
Strictly speaking this is more of network issue rather than a programming one.
The SocketOptionName.Broadcast is not used on internet. UDP via internet will only work with peer-peer.

Categories

Resources