I'm playing around with broadcasting and receiving UDP messages.
I have a client and a server that work ok in my machine, but that can't connect across machines.
My server sends messages and my client receives them.
I turned of the firewall on both machines, that can't be the problem.
The server looks like:
var udpclient = new UdpClient();
IPAddress multicastAddress = IPAddress.Parse("239.0.0.222");
udpclient.JoinMulticastGroup(multicastAddress);
var endPoint = new IPEndPoint(multicastAddress, 2222);
while(true)
{
Byte[] buffer = Encoding.Unicode.GetBytes(Dns.GetHostName());
udpclient.Send(buffer, buffer.Length, endPoint);
Console.WriteLine("Broadcasting server hostname: {0}", Dns.GetHostName());
Thread.Sleep(3000);
}
And the client looks like:
var client = new UdpClient { ExclusiveAddressUse = false };
var ipEndPoint = new IPEndPoint(IPAddress.Any, 2222);
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
client.ExclusiveAddressUse = false;
client.Client.Bind(ipEndPoint);
IPAddress multicastaddress = IPAddress.Parse("239.0.0.222");
client.JoinMulticastGroup(multicastaddress);
Byte[] data = client.Receive(ref ipEndPoint);
string strData = Encoding.Unicode.GetString(data);
Console.WriteLine("Received hostname {0} from the server", strData);
Console.WriteLine("I'm done. Press any key to close me.");
Console.ReadLine();
I think the problem is not in the code, but network related.
Any ideas on how to check what's the problem? Thank you in advance
Try connecting them to a same network such as a wifi network.Note: every time you connect to a different network the IP address changes.
Related
I have found this piece of code on the internet: it does not open a server listening on port 11000, as I hoped.
What can be the problem? I normally code in Delphi, so I am little lost. I have made a corresponding client in Delphi, which works.
I am using demo version of C# 2015.
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and
// listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (true)
{
//Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
data = null;
// An incoming connection needs to be processed.
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("#") > -1)
{
break;
}
}
// Show the data on the console.
//Console.WriteLine("Text received : {0}", data);
// Echo the data back to the client.
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
//Console.WriteLine("\nPress ENTER to continue...");
//Console.Read();
}
The problem might be here: Whats the IP address of ipHostInfo.AddressList[0] ? It might be the loop-back. I never restrict my server endpoint to an ip-adress unless I need to, but then I will specify it in a configfile.
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 11000);
As per Jeroen's answer, encountered per .NET's Synchronous Server Socket Example. When listening/connecting to localhost, one should rather use
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
instead of
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
Thanks for feedback. I found som other, older code:
TcpListener serverSocket = new TcpListener(11000);
that does the job. I know it is depreciated, but it works, actually.
I am trying to make client Server appilcation in c#. On the Client side i write hello message to Server and Server receives the message.
once the Server receive the message, it should send back client a messsage indicating that message has been received. Basically an acknowledment.
My Problem is that Client doesn´t receive the message form Server.
On down is my code for both Client and Server.
Client part:
string x = "192.168.1.4";
IPAddress add = IPAddress.Parse(x);
IPEndPoint point = new IPEndPoint(add, 2789);
using (UdpClient client = new UdpClient())
{
byte[] data = Encoding.UTF8.GetBytes("Hello from client");
client.Send(data, data.Length, point);
string serverResponse = Encoding.UTF8.GetString(client.Receive(ref point));
Console.WriteLine("Messahe received from server:"+ serverResponse);
}
Server part:
try
{
while (true)
{
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 2789);
Console.WriteLine("Client address is:" + groupEP.Address.ToString());
Console.WriteLine("Client port is:" + groupEP.Port.ToString());
byte[]data = new byte[1024];
UdpClient listener = new UdpClient(2789);
Console.WriteLine("Waiting for client");
byte[] bytes = listener.Receive(ref groupEP);
Console.WriteLine("Received Data:"+ Encoding.ASCII.GetString(bytes, 0, bytes.Length));
//sending acknoledgment
string welcome = "Hello how are you from server?";
byte[]d1 = Encoding.ASCII.GetBytes(welcome);
listener.Send(d1, d1.Length, groupEP);
Console.WriteLine("Message sent to client back as acknowledgment");
}
}
I compiled your code and it work so your issue is an "outside" problem such as :
A firewall is blocking something (either the connection or the server binding).
Because the ip in your sample is a lan ip it is probably the built-in firewall from Windows (or a third-party firewall).
Try to disable your firewall, here is how to disable the built-in firewall of Windows.
You test the client on a different computer than the server and use the wrong ip.
If you do test on the same machine you may use the special ip 127.0.0.1 (aka the DNS localhost). 127.0.0.1 always refer to the computer that is running the code. Using this special ip may avoid you trouble in future if your local ip does changes.
And by the way, in your server code you should reuse the "listener" field for each interation of while() such as in
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 2789);
Console.WriteLine("Client address is:" + groupEP.Address.ToString());
Console.WriteLine("Client port is:" + groupEP.Port.ToString());
byte[] data = new byte[1024];
UdpClient listener = new UdpClient(2789);
while (true)
{
Console.WriteLine("Waiting for client");
byte[] bytes = listener.Receive(ref groupEP);
Console.WriteLine("Received Data:" + Encoding.ASCII.GetString(bytes, 0, bytes.Length));
//sending acknoledgment
string welcome = "Hello how are you from server?";
byte[] d1 = Encoding.ASCII.GetBytes(welcome);
listener.Send(d1, d1.Length, groupEP);
Console.WriteLine("Message sent to client back as acknowledgment");
}
I'm using C# to create a client-server network. I created client successfully but i have an issue with the server. When i broadcast a message to the server it's supposed to send it to other clients as well. The problem is that the server too gets the message then it thinks it's another message and it creates an infinite loop that sends the same message over and over again. Can I broadcast excluding the server?
public void serverThread()
{
while (true)
{
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receiveBytes = udpClient_rec.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
if (returnData.StartsWith("broad"))
{
UdpClient udpClient_send = new UdpClient();
IPEndPoint RemoteIpEndPoint1 = new IPEndPoint(IPAddress.Broadcast, 8400);
//can i use something else here instead of broadcast to send it to everyone except myself(server)?
udpClient_send.EnableBroadcast = true;
udpClient_send.Send(receiveBytes, receiveBytes.Length, RemoteIpEndPoint1);
udpClient_send.Close();
}
this.SetText(RemoteIpEndPoint.Address.ToString() + ": " + returnData.ToString());
this.SetText2(RemoteIpEndPoint.Address.ToString());
}
}
For some reason I am having a hard time sending and receiving data from the same socket. Anyways here is my client code:
var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening (testing localy)
client.Connect(ep);
// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);
// then receive data
var receivedData = client.Receive(ref ep); // Exception: An existing connection was forcibly closed by the remote host
Basically I want to create a protocol where I send a udp packet and then I expect a response. Just like the HTTP protocol for every request there is a response. This code works if the server is on a different computer. There might be the case where the server and client are on the same computer though.
Here is the server:
UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);
while (true)
{
var groupEP = new IPEndPoint(IPAddress.Any, 11000); // listen on any port
var data = udpServer.Receive(ref groupEP);
udpServer.Send(new byte[] { 1 }, 1); // if data is received reply letting the client know that we got his data
}
Edit
the reason why I cannot use tcp is because sometimes the client is behind a NAT (router) and it is simpler to do UDP hole punching than TCP.
Solution:
thanks to markmnl answer here is my code:
Server:
UdpClient udpServer = new UdpClient(11000);
while (true)
{
var remoteEP = new IPEndPoint(IPAddress.Any, 11000);
var data = udpServer.Receive(ref remoteEP); // listen on port 11000
Console.Write("receive data from " + remoteEP.ToString());
udpServer.Send(new byte[] { 1 }, 1, remoteEP); // reply back
}
Client code:
var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening
client.Connect(ep);
// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);
// then receive data
var receivedData = client.Receive(ref ep);
Console.Write("receive data from " + ep.ToString());
Console.Read();
(I presume you are aware that using UDP(User Datagram Protocol) does not guarantee delivery, checks for duplicates and congestion control and will just answer your question).
In your server this line:
var data = udpServer.Receive(ref groupEP);
re-assigns groupEP from what you had to a the address you receive something on.
This line:
udpServer.Send(new byte[] { 1 }, 1);
Will not work since you have not specified who to send the data to. (It works on your client because you called connect which means send will always be sent to the end point you connected to, of course we don't want that on the server as we could have many clients). I would:
UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);
while (true)
{
var remoteEP = new IPEndPoint(IPAddress.Any, 11000);
var data = udpServer.Receive(ref remoteEP);
udpServer.Send(new byte[] { 1 }, 1, remoteEP); // if data is received reply letting the client know that we got his data
}
Also if you have server and client on the same machine you should have them on different ports.
I'll try to keep this short, I've done this a few months ago for a game I was trying to build, it does a UDP "Client-Server" connection that acts like TCP, you can send (message) (message + object) using this. I've done some testing with it and it works just fine, feel free to modify it if needed.
here is my soln to define the remote and local port and then write out to a file the received data, put this all in a class of your choice with the correct imports
static UdpClient sendClient = new UdpClient();
static int localPort = 49999;
static int remotePort = 49000;
static IPEndPoint localEP = new IPEndPoint(IPAddress.Any, localPort);
static IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), remotePort);
static string logPath = System.AppDomain.CurrentDomain.BaseDirectory + "/recvd.txt";
static System.IO.StreamWriter fw = new System.IO.StreamWriter(logPath, true);
private static void initStuff()
{
fw.AutoFlush = true;
sendClient.ExclusiveAddressUse = false;
sendClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
sendClient.Client.Bind(localEP);
sendClient.BeginReceive(DataReceived, sendClient);
}
private static void DataReceived(IAsyncResult ar)
{
UdpClient c = (UdpClient)ar.AsyncState;
IPEndPoint receivedIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receivedBytes = c.EndReceive(ar, ref receivedIpEndPoint);
fw.WriteLine(DateTime.Now.ToString("HH:mm:ss.ff tt") + " (" + receivedBytes.Length + " bytes)");
c.BeginReceive(DataReceived, ar.AsyncState);
}
static void Main(string[] args)
{
initStuff();
byte[] emptyByte = {};
sendClient.Send(emptyByte, emptyByte.Length, remoteEP);
}
The following code sends a packet on port 15000:
int port = 15000;
UdpClient udp = new UdpClient();
//udp.EnableBroadcast = true; //This was suggested in a now deleted answer
IPEndPoint groupEP = new IPEndPoint(IPAddress.Broadcast, port);
string str4 = "I want to receive this!";
byte[] sendBytes4 = Encoding.ASCII.GetBytes(str4);
udp.Send(sendBytes4, sendBytes4.Length, groupEP);
udp.Close();
However, it's kind of useless if I can't then receive it on another computer. All I need is to send a command to another computer on the LAN, and for it to receive it and do something.
Without using a Pcap library, is there any way I can accomplish this? The computer my program is communicating with is Windows XP 32-bit, and the sending computer is Windows 7 64-bit, if it makes a difference. I've looked into various net send commands, but I can't figure them out.
I also have access to the computer (the XP one)'s local IP, by being able to physically type 'ipconfig' on it.
EDIT: Here's the Receive function I'm using, copied from somewhere:
public void ReceiveBroadcast(int port)
{
Debug.WriteLine("Trying to receive...");
UdpClient client = null;
try
{
client = new UdpClient(port);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
IPEndPoint server = new IPEndPoint(IPAddress.Broadcast, port);
byte[] packet = client.Receive(ref server);
Debug.WriteLine(Encoding.ASCII.GetString(packet));
}
I'm calling ReceiveBroadcast(15000) but there's no output at all.
Here is the simple version of Server and Client to send/receive UDP packets
Server
IPEndPoint ServerEndPoint= new IPEndPoint(IPAddress.Any,9050);
Socket WinSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
WinSocket.Bind(ServerEndPoint);
Console.Write("Waiting for client");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0)
EndPoint Remote = (EndPoint)(sender);
int recv = WinSocket.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
Client
IPEndPoint RemoteEndPoint= new IPEndPoint(
IPAddress.Parse("ServerHostName"), 9050);
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
string welcome = "Hello, are you there?";
data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);