SetSocketOption not working for SocketOptionName.ChecksumCoverage C# - c#

I am trying to set an option for my UDP socket in C# .Net. I am pretty sure I am doing everything as the Microsoft documents stated; however it is throwing an An 'invalid argument was supplied' exception.
Socket socket;
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Any, port));
// MUST BE BIND FIRST BEFORE SETTING OPTIONS!
// To find out what option can be used with what:
// https://msdn.microsoft.com/en-us/library/1011kecd(v=vs.110).aspx
socket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.NoChecksum, 0);
socket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.ChecksumCoverage, 1);
The exception is thrown right when setting the SocketOptionName.ChecksumCoverage option to 1 or true. I looked through the documents, it should be valid arguments. What am I doing wrong?

Related

Determine if SocketException from UdpClient.Receive was caused by a timeout

I have a UdpClient receiving data with a timeout set, e.g.:
UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 12345));
client.Client.ReceiveTimeout = 5000; // 5 second timeout
while (!shutdown) {
IPEndPoint source = null;
byte[] data = client.Receive(ref source);
}
Receive is documented as throwing a SocketException if "an error occurred when accessing the socket". The behavior of setting ReceiveTimeout is also documented as throwing a SocketException if the synchronous operation times out.
If I get a SocketException from Receive when a timeout is set, how can I determine if the exception was caused by a timeout rather than a more serious error?
I did confirm that the exception thrown on timeout is an actual SocketException and not some specific subclass of it. The only thing I can really think of is checking the exception message, which is a hack that I'm not really excited about.
You need to examine SocketException.ErrorCode property for value 10060 (WSATIMEDOUT).
The complete list of ErrorCode values you can find here: https://learn.microsoft.com/windows/win32/winsock/windows-sockets-error-codes-2

UdpClient not failing when endpoint is unavailable

It was my expectation that, if the endpoint is not available, the UdpClient.Connect() method would throw an exception that I could capture and, say, alter a label's text to say if the program was connected to the server or not. However, despite me having turned off the server that I'm trying to connect to, the method completes with no issue. Is there some way to resolve this issue, or some other method I should be attempting?
My current code (IP address blanked out, but is valid):
UdpClient chatConnection = new UdpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("xxx.xx.xxx.xxx"), 1000);
// Initialize client/server connection and set status text
try
{
chatConnection.Connect(serverEndPoint);
SL_Status.Text = "Connected";
}
catch (Exception ex)
{
SL_Status.Text = "Not Connected";
MessageBox.Show("Unable to connect to server. See console for logs.");
Console.WriteLine(ex);
}
Since UDP is connectionless checking if client is connected doesn't apply to it.
There is however a workaround that in some cases may work:
answer by Yahia

Can't bind a connected socket

So I'm all new to this 'Socket' programming and there seems to be something I have fundamentally misunderstood ...
The documentation for the server I use is very poorly written, but says it uses a "streaming socket connection" that is "event based" ... the server is on the local network.
here is my first naive program flow (no async or anything!):
.........
1) First I need a Socket ... no problem ... I get that :)
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
2) Then I connect with it ... also no problem :)
s.Connect("10.10.10.36", 6009);
3) Now that I have my connection and I have the new local EP given by the server ... something like "10.10.10.59:56231" ... so I try to Bind to that EP :
s.Bind (s.LocalEndPoint);
After that I need to listen and begin accepting connections :
s.Listen (10);
s.Accept ();
.........
the "s.Bind (s.LocalEndPoint);" fails (I ran it without the debugger) with this :
.........
Unhandled Exception:
System.Net.Sockets.SocketException: Invalid arguments
at System.Net.Sockets.Socket.Bind (System.Net.EndPoint local_end) [0x00065] in /private/tmp/source/bockbuild-xamarin/profiles/mono-mac-xamarin-no-pcl/build-root/mono-3.2.0/mcs/class/System/System.Net.Sockets/Socket.cs:1115
at RFID.MainClass.Main (System.String[] args) [0x0002b] in /Users/jab/Projects/RFID/RFID/Program.cs:17
[ERROR] FATAL UNHANDLED EXCEPTION: System.Net.Sockets.SocketException: Invalid arguments
at System.Net.Sockets.Socket.Bind (System.Net.EndPoint local_end) [0x00065] in /private/tmp/source/bockbuild-xamarin/profiles/mono-mac-xamarin-no-pcl/build-root/mono-3.2.0/mcs/class/System/System.Net.Sockets/Socket.cs:1115
at RFID.MainClass.Main (System.String[] args) [0x0002b] in /Users/jab/Projects/RFID/RFID/Program.cs:17
.........
Now I know this is very primitive question but I need to be pointed in the right direction :)
TIA.
The problem occurs because you connectthe socket. But you would only connect the client (not the server). To get a local endpoint to listen on, just create one yourself :
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 6009);
s.Bind (localEndPoint);
After this it should work.
The reason why bind() would not work for a client is because the connect() implicitly binds the client socket to a temporary port number. But, if you try to bind() before connect(), then it would succeed. So, for client side, all you need to do is open a socket and connect. For the server side, you would need to open a socket, bind it to a port, start listening, and then get pending connections using accept().

SocketException: address incompatible with requested protocol

I was trying to run a .Net socket server code on Win7-64bit machine .
I keep getting the following error:
System.Net.Sockets.SocketException: An address incompatible with the requested protocol
was used.
Error Code: 10047
The code snippet is :
IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
IPEndPoint ip = new IPEndPoint(ipAddress, 9989);
Socket serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
try
{
serverSocket.Bind(ip);
serverSocket.Listen(10);
serverSocket.BeginAccept(new AsyncCallback(AcceptConn), serverSocket);
}
catch (SocketException excep)
{
Log("Native code:"+excep.NativeErrorCode);
// throw;
}
The above code works fine in Win-XP sp3 .
I have checked Error code details on MSDN but it doesn't make much sense to me.
Anyone has encountered similar problems? Any help?
On Windows Vista (and Windows 7), Dns.GetHostEntry also returns IPv6 addresses. In your case, the IPv6 address (::1) is first in the list.
You cannot connect to an IPv6 (InterNetworkV6) address with an IPv4 (InterNetwork) socket.
Change your code to create the socket to use the address family of the specified IP address:
Socket serverSocket =
new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
↑
Note: There's a shortcut to obtain the IP address of localhost: You can simply use IPAddress.Loopback (127.0.0.1) or IPAddress.IPv6Loopback (::1).
Edit C:\Windows\System32\drivers\etc\hosts and add the line "127.0.0.1 localhost" (if its not there, excluding quotes)

TCP stuff never works for me

I am trying to get a little client/server thing going just to learn how to do it... But after using many samples, following several tutorials even on msdn, none of them have ever worked.
I keep getting the following exception:
System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 220.101.27.107:8000
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at t.MainForm.toolStripButton1344_Click(Object sender, EventArgs e) in C:\Users\Jason\Documents\Visual Studio 2008\Projects\t\t\MainForm.cs:line 1648
and the code i have is:
private void toolStripButton1344_Click(object sender, EventArgs e)
{
String strHostName;
string ipaddy;
// Getting Ip address of local machine...
// First get the host name of local machine.
strHostName = Dns.GetHostName();
Console.WriteLine("Local Machine's Host Name: " + strHostName);
// Then using host name, get the IP address list..
IPHostEntry ipEntry = Dns.GetHostByName(strHostName);
IPAddress[] addr = ipEntry.AddressList;
for (int i = 0; i < addr.Length; i++)
{
ipaddy = addr[i].ToString();
}
Socket st = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipe = new IPEndPoint(addr[0], 8000);
try
{
st.Connect(ipe);
}
catch (ArgumentNullException ae)
{
MessageBox.Show("ArgumentNullException : {0}" + ae.ToString());
}
catch (SocketException se)
{
MessageBox.Show("SocketException : {0}" + se.ToString());
}
catch (Exception ex)
{
MessageBox.Show("Unexpected exception : {0}" + ex.ToString());
}
}
Can someone please help me understand why this won't work??
Thank you :)
Have you started the server, before trying to connect with the client?
Also, make sure that the port you are using (8000) isn't blocked by a firewall or occupied by another process.
Basically, the error message says the target machine (the one you're trying to connect to) answered the SYN (connection request packet) with an RST (reset, i.e. no connection possible in this case). What it means is, there's no server process listening on the other end.
Client-server software comes in two parts, the client which is connecting to the second part, the server. The server process needs to be listening on a tcp port in order to accept connections, and the client must connect to the servers IP address, along with the port it's listening on.
Well, if all you are trying to do is test creating a socket connection, use "google.com" as your host name and 80 as your port. That is guaranteed to always be listening. And if it's not, then, well, that would probably mean that the world has stopped.
I figured out why it wasn't working. Recently a little application (which I had no idea about) was installed along with a program that I chose to install, and that app was using up several ports. I've managed to get rid of that app, and everything's working just fine :)
Thank you all for your help and suggestions!

Categories