How to use TCP Client in Android without Sockets? - c#

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

Related

IPv4 address 0.0.0.0 and IPv6 address ::0 are unspecified addresses that cannot be used as a target address

I am trying to establish a connection to any IP on that port. Originally, I had it said to 10.0.0.7, which was the IP of another computer on my network, so I could test the client/server. However, I want it to work with any computer without having to change the IP Address to 10.0.0.7 I tried changing it to IPAddress.Any, as the name made it seem like it would accept any IP. Evidently, it didn't because now I'm getting an error. I'm confused. Below is my entire main method, which is the only method so far.
TcpClient client = new TcpClient(IPAddress.Any.ToString() , 1200);
NetworkStream stream = client.GetStream();
string messageToSend;
byte[] messageBytes;
while (true)
{
try
{
Console.WriteLine("Type a message to send");
messageToSend = Console.ReadLine();
messageBytes = Encoding.Unicode.GetBytes(messageToSend);
stream.Write(messageBytes, 0, messageBytes.Length);
}
catch
{
}
Your example can't work with IpAddress.Any.
You have to provide the ip of the server.
A client has to connect to a server with a given IP address.
But a server can listen for any IpAddress.
Reference :
https://msdn.microsoft.com/fr-fr/library/system.net.ipaddress.any(v=vs.110).aspx

Broadcasting UDP message from C# to Python

I'm trying to send a broadcast message from a C# app on one machine to a Python script on another. If I specify the Python machine's IP as my endpoint, I can send a message just fine. Here's how I'm sending my message:
const int PORT = 12345;
using (var sock = new UdpClient())
{
var endpoint = new IPEndPoint(IPAddress.Parse(remoteIP), PORT);
//var endpoint = new IPEndPoint(IPAddress.Broadcast, PORT);
byte[] bytes = Encoding.UTF8.GetBytes("hello, world!");
sock.Send(bytes, bytes.Length, endpoint);
}
On the Python side, I'm receiving as follows:
import socket
PORT = 12345
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', PORT))
#sock.bind(('<broadcast>', PORT))
while 1:
data,addr = sock.recvfrom(1024)
if not data: break
print(data)
I can send my message from one machine to another successfully. However, I have multiple machines to which I want my message to go (UDP broadcast), but when I use IPAddress.Broadcast as my endpoint, Python doesn't receive my message. I've also tried binding my Python socket to <broadcast>, but that doesn't help, and binding to my C# machine's IP gives me the error socket.gaierror: [Errno -3] Temporary failure in name resolution.
I don't know if this is an issue of C# not sending the broadcast or of Python not receiving it.
You can use a network analyzer such as Wireshark to verify the operation of your networking code. I suspect that if you do, you will find that no broadcast datagram is actually set.
Lacking a good, complete code example it's hard to say for sure what the reason would be. But the cause of this would most likely be because you have not set the Socket.EnableBroadcast property for your socket. It defaults to false and if not set to true, broadcast datagrams won't be sent even if you send to a broadcast address.

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.

How to know "The DNS name of the remote host" of a computer?

I have two programs use to communicate with each other via UDP protocol (client and server), but when the client connects to the server using the method Connect (
string hostname,
int port
), Nothing happened.
This is code:
udpclient.Connect("asuspc",6500);
string duongdan = tbduongdan.Text;
Byte[] sendbyte = Encoding.ASCII.GetBytes(duongdan);
udpclient.Send(sendbyte, sendbyte.Length);
"asuspc" is name of computer that i intend to connect.
After a while to find out, I know that the hostname is "The DNS name of the remote host" rather than the name of computer, then what is "The DNS name of the remote host"?How to know "The DNS name of the remote host" of a computer?
By definition, UDP is a connection-less protocol. You do not need to connect in order to send/receive data.
Note that calling Connect() on a UdpClient object does nothing other than setting a default remote host so that you won't have to specify it each time you use the Send method. So don't expect anything to "happen" after the client calls the Connect method.
With that out of the way, if both your server and your client are on your private LAN, why don't you use the computer's IP? e.g.
// replace 192.168.1.44 with the server's private IP
udpclient.Connect("192.168.1.44",6500);
string duongdan = tbduongdan.Text;
Byte[] sendbyte = Encoding.ASCII.GetBytes(duongdan);
udpclient.Send(sendbyte, sendbyte.Length);
Uhm... I think that a bit of TCP/IP reading will help you a lot :-)
Every machine has an assigned IP address. To not have to remember those long IP addresses, DNS servers were created, so you can write "host.domain.com", and your DNS servers tells you that this "machine DNS name" corresponds with the IP address xx.xx.xx.xx.
Said that, to know the "DNS name" of a machine, under windows (and linux) you can write:
nslookup ip_address_of_the_machine
Example: nslookup 192.168.1.2
Hope that helps.
In server side, (code to get ip address only)
// get the ip and port number where the client will be listening on
static IPEndPoint GetClientInfo()
{
// wait for client to send data
using (UdpClient listener = new UdpClient(6500))
{
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 6500);
byte[] receive_byte_array = listener.Receive(ref groupEP);
return groupEP;
}
}
Then to get IP
var ip = clientInfo.Address.ToString();
var port = clientInfo.Port;
UdpClient client = new UdpClient(new IPEndPoint( IPAddress.Any, 6500));
client.Connect(ip, port); // use ip address
Then in client side you can recieve the data using the buffer

Socket communication for inter-WebRole communications in Azure

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.

Categories

Resources