I'm trying to broadcast a message from server to a remote client, my problem is that I'm not able to receive the message on the client, the approach I'm currently playing with is as follows:
//Server
UdpClient udpServer = new UdpClient();
udpServer.Client.Bind(new IPEndPoint(IPAddress.Any, port));
var send = Task.Run(() =>
{
var to = new IPEndPoint(IPAddress.Broadcast, port);
while (true)
{
var response = gameWorld.GetStateJson();
var responseInBytes = Encoding.ASCII.GetBytes(response);
udpServer.SendAsync(responseInBytes, responseInBytes.Length, to);
Console.WriteLine(response);
gameWorld.Update();
}
});
send.Wait();
And for the client:
//Client
UdpClient receivingUdpClient = new UdpClient(8081);
while (true)
{
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Parse("11.111.111.111"), 0);
try
{
byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine(returnData.ToString());
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
So the current client code works as expected, but only for my LAN (if I understand correctly), I'm not sure what should I change in order to be receiving the messages over the internet "globally", advice would be highly appreciated.
Side question: does the server code as is broadcast the data "globally" ? Or is it also for my LAN only?
EDIT: Is this somehow possible or do I have to send data to each client explicitly, even though they're the same for all
Related
Problem:
I am trying to bind a udp socket on a specific address. I will broadcast out a message. That same socket will need to be able to receive messages.
Current code:
static void Main()
{
UdpClient Configuration = new UdpClient(new IPEndPoint(IPAddress.Parse(data.IPAddress), configuration.Port)); //set up the bind to the local IP address of my choosing
ConfigurationServer.EnableBroadcast = true;
Configuration.Connect(new IPEndpoint(IPAddress.Parse(data.BroadcastIP), configuration.Port);
Listen();
}
private void Listen()
{
Task.Run(async () =>
{
while (true)
{
var remoteIp = new IPEndPoint(IPAddress.Any, configuration.Port);
var data = await ConfigurationServer.ReceiveAsync();
// i would send based on what data i received here
int j = 32;
}
}
});
}
I am not receiving data on listen thread. I know that the code on the other side is functional, and sending a directed UDP message to the IP/Port combo.
It can simply be done as
int PORT = 9876;
UdpClient udpClient = new UdpClient();
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, PORT));
var from = new IPEndPoint(0, 0);
var task = Task.Run(() =>
{
while (true)
{
var recvBuffer = udpClient.Receive(ref from);
Console.WriteLine(Encoding.UTF8.GetString(recvBuffer));
}
});
var data = Encoding.UTF8.GetBytes("ABCD");
udpClient.Send(data, data.Length, "255.255.255.255", PORT);
task.Wait();
i have a program that multiple clients would be able to connect to a server using a socket.
private void performConnect()
{
while (true)
{
if (myList.Pending())
{
thrd = thrd + 1;
tcpClient = myList.AcceptTcpClient();
IPEndPoint ipEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint;
string clientIP = ipEndPoint.Address.ToString();
nStream[thrd] = tcpClient.GetStream();
currentMsg = "\n New IP client found :" + clientIP;
recieve[thrd].Start();
this.Invoke(new rcvData(addNotification));
try
{
addToIPList(clientIP);
}
catch (InvalidOperationException exp)
{
Console.Error.WriteLine(exp.Message);
}
Thread.Sleep(1000);
}
}
}
then the server could send data (chat messages) to a chosen client, using this code.
private void sendData(String data)
{
IPAddress ipep =IPAddress.Parse(comboBox1.SelectedItem.ToString());
Socket server = new Socket(AddressFamily.InterNetwork , SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipept = new IPEndPoint( ipep, hostPort);
NetworkStream nStream = tcpClient.GetStream();
ASCIIEncoding asciidata = new ASCIIEncoding();
byte[] buffer = asciidata.GetBytes(data);
if (nStream.CanWrite)
{
nStream.Write(buffer, 0, buffer.Length);
nStream.Flush();
}
}
the problem is that whatever IP i choose from the combo box, the message i send would always be directed/sent to the last IP that connected to the server.. Please somebody help me find the error.. all help would be appreciated, thanks in advance!
That's because in sendData you perform
NetworkStream nStream = tcpClient.GetStream();
where tcpClient variable stores the last accepted connection. Instead of this, you should use your nStream[] array which stores all the connected streams.
I have a program that multiple clients would be able to connect to a server using a socket:
private void performConnect()
{
while (true)
{
if (myList.Pending())
{
thrd = thrd + 1;
tcpClient = myList.AcceptTcpClient();
IPEndPoint ipEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint;
string clientIP = ipEndPoint.Address.ToString();
nStream[thrd] = tcpClient.GetStream();
currentMsg = "\n New IP client found :" + clientIP;
recieve[thrd].Start();
this.Invoke(new rcvData(addNotification));
try
{
addToIPList(clientIP);
}
catch (InvalidOperationException exp)
{
Console.Error.WriteLine(exp.Message);
}
Thread.Sleep(1000);
}
}
}
then the server could send data (chat messages) to a chosen client, using this code.
private void sendData(String data)
{
IPAddress ipep =IPAddress.Parse(comboBox1.SelectedItem.ToString());
Socket server = new Socket(AddressFamily.InterNetwork , SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipept = new IPEndPoint( ipep, hostPort);
NetworkStream nStream = tcpClient.GetStream();
ASCIIEncoding asciidata = new ASCIIEncoding();
byte[] buffer = asciidata.GetBytes(data);
if (nStream.CanWrite)
{
nStream.Write(buffer, 0, buffer.Length);
nStream.Flush();
}
}
the problem is that whatever IP i choose from the combo box, the message i send would always be directed/sent to the last IP that connected to the server.. Please somebody pinpoint my error! all help would be appreciated.
Look at those lines:
IPAddress ipep =IPAddress.Parse(comboBox1.SelectedItem.ToString());
Socket server = new Socket(AddressFamily.InterNetwork , SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipept = new IPEndPoint( ipep, hostPort);
NetworkStream nStream = tcpClient.GetStream();
You are creating a new socket but you are sending the data to the socket stored in the variable tcpClient that is global (since it was not defined in the method), thus totally ignoring the IPEndPoint parsed from the combobox.
You should not create a new socket in order to send data to the clients. Instead, store all clients in a collection and retrieve the appropriate one based on the input of the combobox.
public void send_multicast(string message)
{
UdpClient c = new UdpClient(10102);
Byte[] sendBytes = Encoding.ASCII.GetBytes(message);
IPAddress m_GrpAddr = IPAddress.Parse("224.0.0.1");
IPEndPoint ep = new IPEndPoint(m_GrpAddr,10102);
c.MulticastLoopback=true;
c.JoinMulticastGroup(m_GrpAddr);
c.Send(sendBytes,sendBytes.Length,ep);
Console.WriteLine(message);
}
public string recv_multicast()
{
Console.WriteLine("was here");
String strData = "";
//String Ret = "";
ASCIIEncoding ASCII = new ASCIIEncoding();
UdpClient c = new UdpClient(10101);
// Establish the communication endpoint.
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 10101);
IPAddress m_GrpAddr = IPAddress.Parse("224.0.0.1");
c.JoinMulticastGroup(m_GrpAddr);
Byte[] data = c.Receive(ref endpoint);
strData = ASCII.GetString(data);
//Ret += strData + "\n";
return strData;
}
is there anything wrong with the ports?
the recv method is getting blocked but is not receiving the message?
In wireshark I can see the message going from local addr port 10102 to 224.0.0.1 dest_port 0, but the recv is not getting the msg from the multicast addr.
BTW I am running both instances on the same computer.
reference : http://msdn.microsoft.com/en-us/library/ekd1t784.aspx
**Got the solution:In send routine
IPEndPoint ep = new IPEndPoint(m_GrpAddr,10102);
should be
IPEndPoint ep = new IPEndPoint(m_GrpAddr,10101);
the port of receiving**
You need to enable multicast loopback in order to recieve packets sent by yourself.
http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.multicastloopback.aspx
You should use JoinMulticastGroup on the server side as well as the client side. If that fails, you can also try using Wireshark (google it) to see if the packets are actually sent.
I have written a socket server in c# that will be used as the basic design for a small game project I am part of. The socket server works fine on lan. I able to communicate completely fine between the server and the client. However on the WAN the server receives all the correct messages from the client, but the client receives no messages from the server. Both the client and the server are behind a router but only the server's router has the ports forwarded. When the client connects to the server I get the IP address of the connection. Because the client is behind a NAT, is there more information from the sender that I need to collect? I assume the client could set up port forwarding but that would be VERY counter-productive to the game. Any help I can get is appreciated. If you need code let me know. Thanks in advance.
Used to make the TCP connection from the client
public string ConnectionAttempt(string ServeIP, string PlayUsername)
{
username = PlayUsername;
try
{
connectionClient = new TcpClient(ServeIP,TCP_PORT_NUMBER);
connectionClient.GetStream().BeginRead(readbuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(DoRead), null);
Login(username);
ipAddress = IPAddress.Parse(((IPEndPoint)connectionClient.Client.RemoteEndPoint).Address.ToString());
servIP = new IPEndPoint(ipAddress,65002);
listenUDP = new IPEndPoint(ipAddress, 0);
UDPListenerThread = new Thread(receiveUDP);
UDPListenerThread.IsBackground = true;
UDPListenerThread.Start();
return "Connection Succeeded";
}
catch(Exception ex) {
return (ex.Message.ToString() + "Connection Failed");
}
}
Listens for a UDP message on a thread.
private void receiveUDP()
{
System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
server.Bind(serverIP);
EndPoint RemoteServ = (EndPoint)servIP;
while (true)
{
byte[] content = new byte[1024];
int data = server.ReceiveFrom(content, ref RemoteServ);
string message = Encoding.ASCII.GetString(content);
result = message;
ProcessCommands(message);
}
}
Server TCP connection Listener:
private void ConnectionListen()
{
try
{
listener = new TcpListener(System.Net.IPAddress.Any, PORT_NUM);
listener.Start();
do
{
UserConnection client = new UserConnection(listener.AcceptTcpClient());
client.LineRecieved += new LineRecieve(OnLineRecieved);
UpdateStatus("Someone is attempting a login");
} while (true);
}
catch
{
}
}
Server UDP Listener:
private void receiveUDP()
{
System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any, UDP_PORT);
System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
trans.Bind(serverIP);
System.Net.IPEndPoint ipep = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
System.Net.EndPoint Remote = (System.Net.EndPoint)ipep;
while (true)
{
byte[] content = new byte[1024];
int recv = trans.ReceiveFrom(content,ref Remote);
string message = Encoding.ASCII.GetString(content);
string[] data = message.Split((char)124);
//UpdateStatus(data[0] + data[1]);
UserConnection sender = (UserConnection)clients[data[0]];
sender.RemoteAdd = Remote;
if (data.Length > 2)
{
OnLineRecieved(sender, data[1] + "|" + data[2]);
}
else
{
OnLineRecieved(sender, data[1]);
}
}
}
Setup Information for a user connection Server-side:
Socket trans = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp); //UDP connection for data transmission in game.
public PlayerLoc Location = new PlayerLoc();
public UserConnection(TcpClient client)//TCP connection established first in the Constructor
{
this.client = client;
ipAdd = IPAddress.Parse(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());
ipep = new IPEndPoint(ipAdd, ((IPEndPoint)client.Client.RemoteEndPoint).Port);
this.client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(StreamReciever), null);
}
Method for sending data to individual users:
public void SendData(string data)//UDP only used during transmission
{
byte[] dataArr = Encoding.ASCII.GetBytes(data);
trans.SendTo(dataArr, dataArr.Length,SocketFlags.None, RemoteAdd);
}
The client must start the UDP communication so that it can get a "hole" in the router/firewall. And the UDP server must reply back using the end point referenced in ReceviedFrom