What I thought would be a simple task, has turned into a bit of a nightmare.
What it boils down to now, is I need to create a UDP listener on port 8888, on a specific link local IPv6 address.
I get an exception thrown when the following line is executed:
_udpSoc = new UdpClient(MONITOR_INPUT_EVENT_SOCKET, AddressFamily.InterNetworkV6);
(where MONITOR_INPUT_EVENT_SOCKET is a const int of value 8888)
Having tried to look for support, I even find an MSDN article describing exactly the same line.
The SocketException thrown is "The requested address is not valid in its context" with an ErrorCode of 10049 with a stacktrace of:
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at System.Net.Sockets.UdpClient..ctor(Int32 port, AddressFamily family)
at [my code...]
Alternatively, if I change the problem line to:
_udpSoc = new UdpClient(_groupEp);
(where _groupEp is an IPEndPoint set to IPAddress.Any, with the ScopeId set the the correct interface, and port of MONITOR_INPUT_EVENT_SOCKET)
...and get an exception of "The requested address is not valid in its context", with the same ErrorCode and stack trace as before.
What's going wrong?
Related
I am trying to establish a connection through Sockets to send data (for testing purposes to the local IP address, meaning the computer is sending data to "itself").
Previously, everything worked perfectly fine for weeks throughout the development, meaning the connection could be established, the data could be sent and received and the connection could finally be closed, but a few days later, also after restarting my router, I am getting a SocketException (98) when trying to bind the "listener" Socket to an end point with IPAddress.Any (0.0.0.0) with the message: Address already in use.
The source code has not changed in between. The Socket is supposed to accept any connection from any IP-Address, as it is the "listener" Socket for receiving data.
I am using .NET 6.0.301.
This is a simplified version of the relevant source code:
// In the constructor of the base-class:
IpEndPoint = new IPEndPoint(IPAddress.Any, Port); // Random unused port that also hasn't changed
// ...
// Gets called in the constructor of the derived class
private async Task ReceiveDataAsync()
{
using Socket listener = new(IpEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
try
{
listener.Bind(IpEndPoint); // Fails here!!!
listener.Listen(100);
}
catch(Exception e)
{
Console.WriteLine(e);
throw;
}
while(true)
{
using Socket handler = await listener.AcceptAsync();
// Receive data...
}
}
This method is called only once and the exception throws at the very first cycle of the loop. It is called, of course, long before the attempt to establish a connection to this IP.
It might also be important noting that I didn't close the connection after receiving the data with the Shutdown, DisconnectAsync and Close methods, but this has always been done on the client side after the data had been sent.
And here is the exception:
System.Net.Sockets.SocketException (98): Address already in use
at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at ....ReceiveDataAsync() ...
EDIT:
This is the output of netstat -ntpl | grep 0.0.0.0 while my IDE, JetBrains Rider is running with the relevant project being opened (but it isn't executing):
tcp 0 0 0.0.0.0:31415 0.0.0.0:* LISTEN
10064/dotnet
tcp 0 0 127.0.0.1:42103 0.0.0.0:* LISTEN
9560/Rider.Backend
tcp 0 0 127.0.0.1:33747 0.0.0.0:* LISTEN
9560/Rider.Backend
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
-
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
-
Killing the process, which occupies the port, doesn't have much of an effect, as a new process gets created when I launch the application again.
A Bind on a fixed endpoint inside a while (true) is hugely suspicious. You only need to bind once - a single listener socket can accept any number of client connections. Refactor the code so you only bind and listen once, and then just have the accept in the while loop.
If it can't bind even the first time, then that suggests a rogue process is holding the port, or possibly a firewall problem. But my money would be on a rogue process. If you can't find it, try rebooting - if that fixes it: it was a rogue process (probably your own program started from a debugger, or similar).
I have an Asp.Net application running from AWS, and it has some process that require it to send e-mails automatically (the usual welcome, confirm email, etc...).
I was able to configure it and publish it. It works fine. But as the website enters "Production", I need to run a second application for testing purposes. I'm able to create it, and differentiate which one is being requested by the bindings in IIS.
The issue when both are up and running is that when I try to send an e-mail from the "Production" one, it works fine. But from the "Test" one, I get the following Exception:
[0:] {"$id":"1","Message":"Bad Request:System.Net.Mail.SmtpException: Failure sending mail. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 177.185.201.253:587\r
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)\r
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)\r
--- End of inner exception stack trace ---\r
at System.Net.Mail.SmtpConnection.ConnectAndHandshakeAsyncResult.End(IAsyncResult result)\r
at System.Net.Mail.SmtpTransport.EndGetConnection(IAsyncResult result)\r
at System.Net.Mail.SmtpClient.ConnectCallback(IAsyncResult result)\r
--- End of inner exception stack trace ---\r
at Shappa.BackEnd.Helpers.EmailSender.<NewPhotoRequired>d__2.MoveNext() in C:\\Andre\\Shappa\\Shappa.BackEnd-Dev\\Shappa.BackEnd\\Helpers\\EmailSender.cs:line 112\r
--- End of stack trace from previous location where exception was thrown ---\r
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r
at Shappa.BackEnd.Controllers.AdminController.<PostPhotoReproved>d__2.MoveNext() in C:\\Andre\\Shappa\\Shappa.BackEnd-Dev\\Shappa.BackEnd\\Controllers\\AdminController.cs:line 78"}
My Code to send email is pretty simple:
public async Task<bool> SendEmail(MailMessage message)
{
try
{
using (var smtp = new SmtpClient())
{
var credential = Config.SMTPCredential;
smtp.Credentials = credential;
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
//smtp.Host = "smtp.gmail.com";
//smtp.EnableSsl = true;
#if DEBUG
smtp.Host = "smtp.kinghost.net";
#else
smtp.Host = "smtpi.kinghost.net";
#endif
smtp.EnableSsl = true;
smtp.Port = 587;
await smtp.SendMailAsync(message).ConfigureAwait(false);
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
Any ideas?
I found it. Thanks dlatikay for your comment. It helped me find my stupid mistake.
177.185.201.253:587 this is an IP in Brazil, which meant I was deploying the application in DEBUG mode. Checking the options for publish, I was able to change it to Release. Now it works perfectly from both applications.
string ipAddress = "a.b.c.d";
IPAddress ipAddr = IPAddress.Parse(ipAddress);
IPEndPoint endPoint = new IPEndPoint(ipAddr, port);
EndPoint remote = (EndPoint)endPoint;
socket.ReceiveFrom(data, ref remote);
I have an intermittent problem, when I am trying to read data from a UDP socket. I tell it which IP address and port I want to read from - rarely, a packet from a different IP address is received under this one?
The silent exception (when I hover over ipAddr) is:
'ipAddr.ScopeId' threw an exception of type 'System.Net.Sockets.SocketException'
If I catch this whilst debugging, and I look at the objects 'endPoint' and 'remote' - endpoint is the correct ip address, but the ip address of remote has changed (of its own accord after this exception, this is NOT a problem with my logic) to the actual ip address it received from, but not the one that it requested from!
ReceiveFrom works 99% of the time, what does this exception mean, why Microsoft why?
The problem is, once that packet is read, it is read, and not passed onto where ever it was meant to go, how can I prevent this?
edit: scopeID is for IPV6, but I don't care for ipv6 so maybe I am looking in the wrong place, but this still doesnt explain why 'endpoint' is not properly resolved to 'remote' (IPEndPoint cast to abstract EndPoint) -- 172.50.2.111 doesnt exist and 99% of the time it times out, but why is it picking up other packets?! cries
). I got into a bit of issues today with the TcpListener. Things are strange. Initially, I used the new TcpListener(port) constructor, but that has been marked as obsolete. So I dropped it and used this instead:
IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, ServerPort);
TcpListener tcpServer = new TcpListener(ipLocalEndPoint);
_TCPClient = tcpServer.AcceptTcpClient();
GotClient();
I do that in a thread, of course, so that it doesn't lock the application. Now, what happens there, is that even though the ipAddress is correct, the server NEVER accepts ANY incoming connection.
HOWEVER, changing to new IPEndPoint(IPAddress.Any, ServerPort) seems to do the trick! Which is silly in 2 ways:
2 hours ago, IPAddress.Any returned 192.168.1.102 which is my correct local IP. This is the same IP which was in ipAddress! But with ipAddress it didn't work, while with IPAddress.Any it worked (that is, it successfully accepted connections from my client).
Right now: IPAddress.Any returns 0.0.0.0 (!?) while the ipAddress variable continues to be assigned my correct IP (192.168.1.102). The result? My client still cannot connect if using ipAddres, but connects when using IPAddress.Any, even though it is 0.0.0.0.
I'm totally puzzled by this... Any thoughts?
I currently have this in Form_HandleCreated but it was acting weird when I had it in the Form's constructor as well.
LATER EDIT: I think I'm wrong about IPAddress.Any returning 192.168.1.102. I probably printed out something else, as many of you have indicated 0.0.0.0 is what .Any should return. Sorry ::- D.
IPAddress.Any should return 0.0.0.0, that is normal. Are you actually sure it returned something else initially?
As for why you couldn't connect before, if you were listening on 192.168.1.102, and tried to connect to 127.0.0.1 (localhost), then it wouldn't work. You need to listen on 127.0.0.1 if you want to connect to that IP address.
Essentially, you must listen on the IP address you are attempting to connect to. Listening on 0.0.0.0 means, "listen on all available IP addresses". Remember, 127.0.0.1 (localhost) is not a synonym for "my local network IP".
0.0.0.0 is blank IP address meaning "I don't care which IP you would use" - i.e. it means you want to listen on all interfaces. It is documented it should return it.
To later edit: First of all dont call [0]. Your hostname may not have any record associated. Even if it do you a) don't know the order b) you don't know where they are (i.e. it may be only 127.0.0.1 i.e. loopback).
On mono such code work (checked with netstat etc.):
using System;
using System.Net;
using System.Net.Sockets;
public class test {
public static void Main(String[] args) {
IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 8888);
TcpListener tcpServer = new TcpListener(ipLocalEndPoint);
tcpServer.Start(); // Without this line there is exception
var _TCPClient = tcpServer.AcceptTcpClient();
}
}
I'm guessing it always returned 0.0.0.0...
I'm trying to create a small HTTP server in C# but I'm having some trouble with IPv6 clients. I have IPv6 support on my machine but when I try to create a listening socket it fails.
Log("Creating server socket on port {0}", LogType.Info, _port);
_serversocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
_serversocket.Bind(new IPEndPoint(IPAddress.Any, _port));
_serversocket.Listen(10);
What am I doing wrong here?
The code throws this exception:
The system detected an invalid pointer address in attempting to use a pointer argument in a call
EDIT:
Stack Trace:
at System.Net.Sockets.Socket.DoBind(EndPoint
endPointSnapshot, SocketAddress
socketAddress) at
System.Net.Sockets.Socket.Bind(EndPoint
localEP) at
TroutServer.Trout.Start(Int32 port) in
C:\Users\Chris\Documents\Visual Studio
2008\Projects\TroutServer\trout\trout.cs:line
62
Type is SocketException
Try:
new IPEndPoint(IPAddress.IPv6Any, _port)