UDP C# connection - c#

I have a program shown below:
Socket receiveSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
EndPoint bindEndPoint = new IPEndPoint(IPAddress.Any, 3838);
byte[] recBuffer = new byte[256];
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
receiveSocket.Bind(bindEndPoint);
receiveSocket.Receive(recBuffer);
}
and it is working but when I want to just listen to a specific IP address it does not work,
it throws an exeption "the requested address is not valid in context"
new code:
EndPoint bindEndPoint = new IPEndPoint(IPAddress.Parse("192.168.40.1"), 3838);

The IP addresses you are binding to, should be one of the IP addresses that are actually assigned to the network interfaces on your computer.
Let's say you have an ethernet interface and a wireless interface
ethernet: 192.168.1.40
wireless: 192.168.1.42
When calling the Bind method on your socket, you are telling it on which interface
you want to listen for data. That being either 'any of them' or just the ethernet interface for example.
I'm guessing this is not what you are looking for?
Perhaps you are trying to restrict who can make a connection to your server
So whate you may be looking for is
var remoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.40"), 0)
receiveSocket.ReceiveFrom(buffer, remoteEndpoint);
This restricts the source from which you accept data.

Related

Able to get a connection with TCPClient but not TCPListener [duplicate]

This question already has answers here:
The requested address is not valid in its context when I try to listen a port
(3 answers)
Closed 5 years ago.
I am currently trying to read in messages from a port and for some reason I am able to do this using a TCPClient however I am recieving an error when trying to use a TCPListener. I was wondering if anyone could tell me why, or where I may be going wrong?
This is the code which works, and I am able to read messages from:
public static NetworkStream nwStream;
public static TcpClient client = new TcpClient();
public const string address = "10.10.10.151";
public const int port = 9004; //both never change
public MainWindow()
{
InitializeComponent();
client.Connect(address, port);
connected = true;
if (connected == true)
{
readInTxtBox.Text = "Connected";
}
}
And this is the code which throws an error:
static void Main(string[] args)
{
IPAddress ipAddress = IPAddress.Parse("10.10.10.151");
TcpListener Listener = new TcpListener(ipAddress, 9004);
Listener.Start(); //this is where the error is!
Socket Client = Listener.AcceptSocket();
using (NetworkStream PMS_NS = new NetworkStream(Client))
{
StreamReader sr = new StreamReader(PMS_NS);
Console.WriteLine(sr.ReadLine());
}
Console.ReadLine();
}
The error says:
An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
Additional information: The requested address is not valid in its contexts
You can only bind to a local IP of the machine you're running on - presumably 10.10.10.151 isn't one. You can use IPAddress.Any to bind to any available interface, which is usually the desired behaviour for a Server. Alternatively, use the TCPListener.Create static function to just specify the port and skip specifying the IP.
If you do want to bind to a specific local IP then your current approach should be fine, just use an IP that's assigned to one of your network interfaces (see ifconfig on Windows or ip a on linux) instead of 10.10.10.151.
Maybe the given IP Adress is not your IP adress. Try to use
TcpListener Listener = new TcpListener(IPAdress.Any, 9004);
instead of
IPAddress ipAddress = IPAddress.Parse("10.10.10.151");
TcpListener Listener = new TcpListener(ipAddress, 9004);

How to properly change a static IP address using the Microframework?

I have my Netduino Plus 2 go out to a web service to look up some values that I would like it to use in my project. One of the values that I have the Netduino check is its preferred IP address. If the Netduino has a different IPAddress than its preferred, I want to change it.
I have a method in my project called BindIPAddress (below) that takes a string.
I am getting a SocketException with a code of 10022 for invalid argument. This happens when I call this.Socket.Bind. My class has a property called Socket to hold the Socket value. Is it because my socket already has an endpoint ? I tried adding this.Socket = null and then this.Socket = new (....... thinking we need a new socket to work with, but this returned the same error.
Please advise how I can change my IP address from one static IP address to another.
public void BindIPAddress(string strIPAddress)
{
try
{
Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].EnableStaticIP(strIPAddress, "255.255.240.0", "10.0.0.1");
Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].EnableStaticDns(new string[] { "10.0.0.2", "10.0.0.3" });
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(strIPAddress), 80);
this.Socket.Bind(ep);
this.IpAddress = strIPAddress;
}
catch(SocketException exc)
{
Debug.Print(exc.Message);
Debug.Print(exc.ErrorCode.ToString());
}
catch(Exception ex)
{
Debug.Print(ex.Message);
}
//Debug.Print(ep.Address.ToString());
}
There may be 2 possible solutions to this problem. The first one is, you can programatically set the preffered IP addresses as the way you have tried to do so and the second one is, you can use MFDeploy tool, which comes with .NET Micro Framework SDK bundle that allows you to set your embedded device network configuration statically before running your application on it.
1) Since you have not provided rest of the code, here's a proper way to bind your socket to an EndPoint (actually, I would not design that class and binding function as the way you posted here, but just wanted to underline the missing parts of your code):
public void BindIPAddress(string strIPAddr)
{
Socket sock = null;
IPEndPoint ipe = null;
NetworkInterface[] ni = null;
try
{
ipe = new IPEndPoint(IPAddress.Parse(strIPAddr), 80);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Assuming the WebService is connection oriented (TCP)
// sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // if it broadcasts UDP packets, use this line (UDP)
ni = NetworkInterface.GetAllNetworkInterfaces();
if (ni != null && ni.Length > 0)
{
ni[0].EnableStaticIP(strIPAddr, "255.255.240.0", "10.0.0.1");
ni[0].EnableStaticDns(new string[2] { "10.0.0.2", "10.0.0.3" });
sock.Bind(ipe);
this.Socket = sock;
this.IpAddress = strIPAddr;
}
else
throw new Exception("Network interface could not be retrieved successfully!");
}
catch(Exception ex)
{
Debug.Print(ex.Message);
}
}
2) Or without programming, just by using MFDeploy tool you can set the preferred IP addresses after plugging your embedded device into your PC and following the path below:
MFDeploy > Target > Configuration > Network
then enter the preferred IP addresses. That's simply all.

sockets - UDP Send data via internet

I've made a simple chat application in c#.net that sends and receives data between 2 computers.
So, I used this method to send the data:
int port = 11000;
private void send(string data, string ip)
{
Socket sending_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint sending_end_point = null;
byte[] send_buffer = Encoding.ASCII.GetBytes(data);
sending_end_point = new IPEndPoint(IPAddress.Parse(ip), port);
try { sending_socket.SendTo(send_buffer, sending_end_point); }
catch { }
}
And to receive I used this:
string receiveddata = "";
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
UdpClient listener = new UdpClient(port);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, port);
byte[] receive_byte_array;
try
{
receive_byte_array = listener.Receive(ref groupEP);
receiveddata = Encoding.ASCII.GetString(receive_byte_array, 0, receive_byte_array.Length);
}
catch { }
listener.Close();
}
This works without any problems between 2 computers on a LAN, but I would like to know (if possible) how to do the same thing over the Internet.
From what I've searched on the Internet, it seems that I have to use port-forwarding in order to do that, so I already did that, but I don't know what should I do know.
So my question is, how should I change this code (if I have to) so I could send and receive data (UDP) over the internet, assuming I have port-forwarded correctly already and assuming I know the external IPs of both routers?
Thank you in advance.
This should work just fine, as long as your (public) IP-address is correct and the ports are forwarded correctly on your router (meaning, forwarded to the correct private IP, on the correct protocol, in your case UDP).
You are aware that this is UDP though, so it's not reliable data transfer.

Socket.RemoteEndPoint returns gateway address

For some reason the C# socket.RemoteEndPoint started returning the address of the default gateway. It used to work and I know the code hasn't changed. I'm not sure when it started occurring as the logs don't go back far enough so I'm not sure what could have happened to this server to cause this. Everything seems to be working normally. Just not getting the remote IP anymore.
Anyone have any idea what could cause this?
Here is the relevant code.
public void startClientListening(string ipString, int port)
{
IPAddress ip = IPAddress.Parse(ipString);
// Create the listening socket...
clientListenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint(ip, port);
// Bind to local IP Address...
clientListenerSocket.Bind(ipLocal);
// Start listening...
clientListenerSocket.Listen(32);
// Create the call back for any client connections...
clientListenerSocket.BeginAccept(onClientConnect, clientListenerSocket);
}
private void onClientConnect(IAsyncResult asyn)
{
Socket workerSocket = clientListenerSocket.EndAccept(asyn);
workerSocket.NoDelay = true;
//This returns 192.168.1.1 rather than the remoteIp
string remoteIp = ((IPEndPoint)workerSocket.RemoteEndPoint).Address.ToString();
}
This could happen if the default gateway was a router/ip firewall before but now it is a proxy/application firewall.
In this case the ip connection is instantiated by the proxy and therefore you see the ip address of the proxy and not of the real client.

IpEndPoint Problem

The prog in c#:
private void listBox1_Click(object sender, EventArgs e)
{
String data = (String)this.listBox1.SelectedItem;
data = data.TrimEnd(new char[] { '\r', '\n' });
try
{
ip = Dns.GetHostAddresses(data);
}
catch (SocketException ex)
{
MessageBox.Show(ex.ErrorCode.ToString());
}
clientIP = new IPEndPoint(ip[0], 6000);
newSock.Bind(clientIP);
newSock.Listen(100);
resetEvent.Set();
}
In the above code, I obtain the ip-address of the remote host who is shown in the listbox and correspondingly in order to start accepting messages need to create an IPEndPoint(clientIP).
newSock is a variable of type socket initialized as:
newSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
The problem is in the line where I bind the socket newSock to the IPEndPoint clientIP where I am getting an error saying it is an invalid address.
However to cross check I tried to display the ip-address on a message box which it did correctly.
So what exactly is going wrong??
You shouldn't bind a socket to remote host address. It's used to indicate on which inbound IP address you should listen. You should either specify one of your own IP addresses (if you want to listen only on a single IP) or specify IPAddress.Any (0.0.0.0) to listen on all IP addresses you have.
By the way, if you want to connect to a remote address, you shouldn't use Bind at all. You'd just use the Connect method

Categories

Resources