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());
}
}
Related
So I'm trying to create a chat application but I'm new to sockets. I have followed a tutorial to create a server and client, however, the server does not broadcast the data sent from one client to every client connected to it. Instead, it only broadcasts it to the client that sent the data.
I have tried to add every client who joins the server to a list and then use a foreach loop to send the data received from one client to every client in the list. This, however, has not worked. I suspect that the error is in the foreach loop but I am not completely certain.
Here is my code for the server:
class Program
{
public static List<Socket> connectedClient = new List<Socket>();
public static Socket clientSocket = default(Socket);
static void Main(string[] args)
{
int port = 13000;
string IpAddress = "127.0.0.1";
Socket serverListener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(IpAddress), port);
serverListener.Bind(ep);
serverListener.Listen(0);
Console.WriteLine("Server running");
Program p = new Program();
int counter = 0;
while (true)
{
counter++;
clientSocket = serverListener.Accept();
connectedClient.Add(clientSocket);
Console.WriteLine(counter + " Client joined");
Thread clientThread = new Thread(new ThreadStart(() =>
p.User(clientSocket)));
clientThread.Start();
}
}
public void User(Socket client)
{
while (true)
{
byte[] msg = new byte[1024];
int size = client.Receive(msg);
Console.WriteLine("Client>> " +
System.Text.Encoding.ASCII.GetString(msg, 0, size));
//the loop that i tried to implement
foreach(Socket clientSocket in connectedClient)
{
client.Send(msg, 0, size, SocketFlags.None);
}
}
}
}
Instead of the message being broadcasted once to all clients, the server sends the message back to the client who sent it but times how many clients there are.
For example: If there are 4 clients connected to the server and one client sends a message "Hello" the server will send back "HelloHelloHelloHello" but only to the client who sent the "Hello".
In
foreach(Socket clientSocket in connectedClient)
{
client.Send(msg, 0, size, SocketFlags.None);
}
You are looping over the clientSockets, but you are Sending on the client, not the clientSocket. If you do clientSocket.Send instead, you should get the expected behavior (e.g. send to each client instead of to one client 4 times).
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 am looking for some help with communication between my server application and my client.The idea is that my client will listen for a UDP packet, read it and then execute a command based on what it reads.
My issue is that the server sends the packet however the client does nothing.
Here is a snippet of my code:
Client:
public void listen()
{
try
{
MessageBox.Show("");
UdpClient receivingUdpClient = new UdpClient(11000);
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 11000);
try
{
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
string[] split = returnData.Split(':');
if (split[0] == "SayHello")
{
MessageBox.show("Hello user","Hello");
}
//Note i have many commands but i shortened it to save room.
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Server:
else if (radioButton4.Checked)
{
UdpClient udpClient = new UdpClient([IP_ADDRESS_HERE], 11000);
body = richTextBox1.Text;
title = textBox1.Text;
Command = "Message" + ":" + body + ":" + title + ":" + 4;
Byte[] sendBytes = Encoding.ASCII.GetBytes(Command);
try
{
udpClient.Send(sendBytes, sendBytes.Length);
}
catch (Exception)
{
Console.WriteLine(e.ToString());
}
}
Just wanted to see if you guys are able to find something I overlooked.
Check your Windows Firewall and verify it's not blocking your Client from opening port 11000.
Control Panel-> System and Security -> Windows Firewall
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.
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);
}