I am not able to receive my own Mcast packets C# UdpClient - c#

I am not able to receive back my own packets send on multicast. i created two Udpclient receiver is to receive packets on multicast group and sender is to send packets. my packets are send to the group but i cannot receive back the packets send by me....
public void Join()
{
IPAddress ip1 = IPAddress.Any;
localep = new IPEndPoint(ip1, port);
Receiver = new UdpClient();
Receiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
Receiver.Client.Bind(localep);
Sender = new UdpClient();
Sender.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
Sender.Client.Bind(localep);
IPAddress ip = IPAddress.Parse(IP);
remoteep = new IPEndPoint(ip, port);
Sender.JoinMulticastGroup(ip);
Sender.EnableBroadcast = true;
Sender.MulticastLoopback = true;
Receiver.JoinMulticastGroup(ip);
Receiver.EnableBroadcast = true;
Receiver.MulticastLoopback = true;
udpState.ipEndpt = RemoteIpEndPoint;
udpState.udpClient = Receiver;
Receiver.BeginReceive(new AsyncCallback(GetMsg), udpState);
}
void GetMsg(IAsyncResult ar)
{
UdpClient udpClient = (UdpClient)((UdpState)(ar.AsyncState)).udpClient;
IPEndPoint ipEndpt = (IPEndPoint)((UdpState)(ar.AsyncState)).ipEndpt;
RecByte = Receiver.EndReceive(ar, ref ipEndpt);
}
//Sending packets logic
McastOTS.Sender.Send(sendBytes, sendBytes.Length, McastOTS.remoteep);

Seems to me all you need to do is call BeginReceive again after your EndReceive. Otherwise, you'll only get 1 message and won't see any others...
void GetMsg(IAsyncResult ar)
{
UdpClient udpClient = (UdpClient)((UdpState)(ar.AsyncState)).udpClient;
IPEndPoint ipEndpt = (IPEndPoint)((UdpState)(ar.AsyncState)).ipEndpt;
RecByte = Receiver.EndReceive(ar, ref ipEndpt);
Receiver.BeginReceive(GetMsg, udpState);
}

Related

UDP Client server works on same computer but not over lan

I have a simple application that sends continuous UDP packets from a server to a client. Everything works well if the server app and client app are on the same computer but the minute I move the client to another computer in the LAN it stops working with a message
"the requested address is not valid in its context". I really don't understand why this is happening.
Here is the server code:
public void SendData()
{
udpClient = new UdpClient();
for (int i = 0; i < 8192; i++)
{
dataBytes[i] = Convert.ToByte(Convert.ToInt16(dataValues[i]));
}
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
try
{
udpClient.Connect(ipAddress, port);
udpClient.Send(dataBytes, dataBytes.Length);
}
catch (Exception ex)
{
}
}
On the client machine here is the code:
private void receive()
{
try
{
udpClient = new UdpClient();
udpClient.Client.ReceiveTimeout = 1000;
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
int port = Convert.ToInt32("13064");
IPAddress ipAddress = IPAddress.Parse("192.168.1.107");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
socket = new UdpClient(localEndPoint);
udpClient.Connect(ipAddress, port);
socket.BeginReceive(new AsyncCallback(ReceivedDataCallback), socket);
}
catch (Exception ex)
{
if (!socketConnected)
{
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ReceivedDataCallback(IAsyncResult AR)
{
try
{
socketConnected = true;
clientSocket = AR.AsyncState as UdpClient;
var port = Convert.ToInt32("13064");
IPAddress ipAddress = IPAddress.Parse("192.168.1.107");
IPEndPoint source = new IPEndPoint(ipAddress, port);
nums = clientSocket.EndReceive(AR, ref source);
OutputRemoteSamples();
clientSocket.BeginReceive(new AsyncCallback(ReceivedDataCallback), clientSocket);
}
catch (Exception ex)
{
}
}
Thanks for any suggestions
Tom

How to know what UDP port using to send a message

I have a program that sends a message to a server and the server recognizes the message inteprets it and sends back the message to the port it was listening from in the begining. so let's say the client sends from port 5000. The server will read the message from port 5000, and send back a message to the port the client used to send the message so the client can receive it. My question now is that I don't want to fix a port for the server ( i don't want the server to always send back to client to port 1000), so how can i know what port my client used to send the message every single time? So in my client, my UdpClient Listener = new UdpClient(xxx) [(xxxx) being the port number] can be filled by a new value every single time? the value of the port it used to send the message
thanks
here's my program :
private const int sendPort = 9999;
static void Main(string[] args)
{
Boolean done = false;
IPAddress send_to_address = IPAddress.Parse("xx.xxx.xxx.xxx");
IPEndPoint sending_end_point = new IPEndPoint(send_to_address, sendPort);
IPEndPoint receiving_end_point = new IPEndPoint(IPAddress.Any, 0);
UdpClient Listener = new UdpClient(WHAT TO PUT HERE???);
while (!done)
{
Socket sending_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
Console.WriteLine("Enter text to send");
string text_to_send = Console.ReadLine();
// the socket object must have an array of bytes to send.
// this loads the string entered by the user into an array of bytes.
byte[] send_buffer = Encoding.ASCII.GetBytes(text_to_send);
// Remind the user of where this is going.
Console.WriteLine("sending to address: {0} port: {1}", sending_end_point.Address, sending_end_point.Port);
sending_socket.SendTo(send_buffer, sending_end_point);
Console.WriteLine("Message has been sent to the broadcast address");
Console.WriteLine("Now we are waiting for a message back from the Listener");
// here we receive the Message from the Server
Byte[] ByteFromListener = Listener.Receive(ref receiving_end_point);
string datafromreceiver = Encoding.ASCII.GetString(ByteFromListener);
Console.WriteLine(Datafrom receiver)
}
}
}
}
The answer was quite simple. Just needed to use the same socket to receive the message.
Here is the code :
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class Program
{
private const int sendPort = 9999;
static void Main(string[] args)
{
Boolean done = false;
IPAddress send_to_address = IPAddress.Parse("10.128.105.177");
IPEndPoint sending_end_point = new IPEndPoint(send_to_address, sendPort);
EndPoint receiving_end_point = new IPEndPoint(IPAddress.Any, 0);
while (!done)
{
Socket sending_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
Console.WriteLine("Enter text to send");
string text_to_send = Console.ReadLine();
// the socket object must have an array of bytes to send.
// this loads the string entered by the user into an array of bytes.
byte[] send_buffer = Encoding.ASCII.GetBytes(text_to_send);
// Remind the user of where this is going.
Console.WriteLine("sending to address: {0} port: {1}", sending_end_point.Address, sending_end_point.Port);
sending_socket.SendTo(send_buffer, sending_end_point);
Console.WriteLine("Message has been sent to the broadcast address");
Console.WriteLine("Now we are waiting for a message back from the Listener");
Byte[] ByteFromListener = new byte[8000];
sending_socket.ReceiveFrom(ByteFromListener, ref receiving_end_point);
string datafromreceiver;
datafromreceiver = Encoding.ASCII.GetString(ByteFromListener).TrimEnd('\0');
//Here we print the message from the server
Console.WriteLine(datafromreceiver.ToString());
}
}
}
}

C# socket custom string

I'm sending socket with this function:
public static List<Socket> samp = new List<Socket>();
IPHostEntry host = null;
Socket sock;
host = Dns.GetHostEntry(serverip);
foreach (IPAddress address in host.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, 7777);
sock = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(ipe);
if (sock.Connected)
{
samp.Add(sock);
}
}
samp.Add(sock); sends my ip, for example 127.0.0.1, how can I add string to ip? For example: Nickname:127.0.0.1 ? Thanks in advance! Or how can I send two sockets? For example:
First socket - nickname
Second - ip
Thnx alot

Connecting two UDP clients to one port (Send and Receive)

I tried the suggestion from this question with very little success.
Please... any help will be greatly appreciated!
Here is my code:
static void Main(string[] args)
{
IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);
UdpClient udpServer = new UdpClient(localpt);
udpServer.Client.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
UdpClient udpServer2 = new UdpClient();
udpServer2.Client.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer2.Client.Bind(localpt); // <<---------- Exception here
}
You have to set the socket option before binding.
static void Main(string[] args)
{
IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);
UdpClient udpServer = new UdpClient();
udpServer.Client.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer.Client.Bind(localpt);
UdpClient udpServer2 = new UdpClient();
udpServer2.Client.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer2.Client.Bind(localpt); // <<---------- No Exception here
Console.WriteLine("Finished.");
Console.ReadLine();
}
Or a more illustrative example:
static void Main(string[] args)
{
IPEndPoint localpt = new IPEndPoint(IPAddress.Loopback, 6000);
ThreadPool.QueueUserWorkItem(delegate
{
UdpClient udpServer = new UdpClient();
udpServer.ExclusiveAddressUse = false;
udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer.Client.Bind(localpt);
IPEndPoint inEndPoint = new IPEndPoint(IPAddress.Any, 0);
Console.WriteLine("Listening on " + localpt + ".");
byte[] buffer = udpServer.Receive(ref inEndPoint);
Console.WriteLine("Receive from " + inEndPoint + " " + Encoding.ASCII.GetString(buffer) + ".");
});
Thread.Sleep(1000);
UdpClient udpServer2 = new UdpClient();
udpServer2.ExclusiveAddressUse = false;
udpServer2.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer2.Client.Bind(localpt);
udpServer2.Send(new byte[] { 0x41 }, 1, localpt);
Console.Read();
}
I looked up your error message and this explains what the error is and why it is happening.
Here is the exact error message and reason WSAEACCES 10013 (MSDN)
Permission denied.
An attempt was made to access a socket in a way forbidden by its
access permissions. An example is using a broadcast address for sendto
without broadcast permission being set using setsockopt(SO_BROADCAST).
Another possible reason for the WSAEACCES error is that when the bind
function is called (on Windows NT 4.0 with SP4 and later), another
application, service, or kernel mode driver is bound to the same
address with exclusive access. Such exclusive access is a new feature
of Windows NT 4.0 with SP4 and later, and is implemented by using the
SO_EXCLUSIVEADDRUSE option.
Even changing your code so that I can pass in an IP address I gets the same error message it appears that you can't bind to the same port and only one port can be used
here is the sample code I used your example and Altered it to capture my ip from my local machine..
IPAddress ipAddress = Dns.Resolve(Dns.GetHostName()).AddressList[0];
IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 11000);
//IPEndPoint localpt = new IPEndPoint(ipLocalEndPoint);
UdpClient udpServer = new UdpClient(ipLocalEndPoint);
udpServer.Client.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer.Connect(ipLocalEndPoint);
UdpClient udpServer2 = new UdpClient();
udpServer2.Client.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer2.Client.Bind(ipLocalEndPoint); // <<---------- Exception here
this will produce the exception on the Bind () method.. sorry.
To solve WSAEACCESS 10013 (MSDN) exception in UDP application you can try
udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);

How to get IP address with a host name?

I am making a client that connect to a server that is locally hosted that gets stock numbers from the server. The program does work if i use this code below but the way it works is by getting the dns name so in theory it only takes www.website.com and I cant figure out how I can get it to recognize a normal ip of 127.0.0.1 or localhost IP:
IPHostEntry ipHostInfo = Dns.GetHostEntry("www.website.com");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
Attached is my attemp to get this to resolve the ip but I dont think I am approaching this right the full code can be seen here:StockReader Client Code
public class AsynchronousClient
{
private const int port = 21;
// ManualResetEvent instances signal completion.
private static ManualResetEvent connectDone =
new ManualResetEvent(false);
private static ManualResetEvent sendDone =
new ManualResetEvent(false);
private static ManualResetEvent receiveDone =
new ManualResetEvent(false);
// The response from the remote device.
private static String response = String.Empty;
private static void StartClient()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// The name of the
//******************ISSUE BEGINS HERE*********************************
string sHostName = Dns.GetHostName();
IPHostEntry ipHostInfo = Dns.GetHostEntry(sHostName);
IPAddress [] ipAddress = ipHostInfo.AddressList;
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
// Send test data to the remote device.
Send(client, "This is a test<EOF>");
sendDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();
// Write the response to the console.
Console.WriteLine("Response received : {0}", response);
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
When you set the value of ipAddress, you can use the IPAddress.Parse method to pass in a string and retrieve an IPAddress object instead of using the domain name:
string ip = "127.0.0.1";
IPAddress address = IPAddress.Parse(ipAddress);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
Try using string sHostName = "localhost";
// Establish the remote endpoint for the socket.
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteEP = new IPEndPoint(ipAddress, portnumber);
// Create a TCP/IP socket.
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect(remoteEP);

Categories

Resources