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)
Related
I am trying to accomplish Tcp hole punching with socket option as reuse address.
First step- Run and tcp listener in server S with active open tcp port 8001.
Second step- Run a Tcp socket with reuse address(method name is enableReuseAddres(Socket sck) mentioned below) in socket option on client A which is behind the NAT on port 8001.
Third step- Connect A => S.
Fourth step- Send data from A => S and get confirm data from S => A.
Fifth step- Get remote endpoint of A which is X.X.X.X:8001(External IP and Port of A).
Sixth Step- Listen on a socket with port 8001(method name is runServer mentioned below),in client A with reuse address(method name is enableReuseAddres(Socket sck) mentioned below) in socket option.
Disclaimer:- No error found and able to bind the same endpoint which is used to connect to the server S with the help of ReuseAddress and able to listen on the same port 8001.
But when I try to check the port 8001 is opened or closed I always get port is closed,of client A.
public void runServer()
{
Socket sk = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
enableReuseAddres(sk);
sk.Bind(loclEP);
sk.Listen(1);
var connection_socket = sk.Accept();
MessageBox.Show("Connected");
}
IPEndPoint loclEP = new IPEndPoint(IPAddress.Any, 8001);
public void enableReuseAddres(Socket sck)
{
sck.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, true);
sck.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.KeepAlive, true);
}
I am trying to send strings to a server using Synchronous WebSockets in a C# console application. The following code works flawlessly on 127.0.0.1 but doesn't work on any real server I tried. The result I get is that the client connects to the IP/Port and sends strings with no errors, but _serverSocket.Accept(); never triggers when _clientSocket.Connect(_IP, _PORT); is called.
Also, if serverSocket.Bind(new IPEndPoint(IPAddress.Any, _PORT)); is not called, then the sender gets an error (as expected) when trying to connect. So it seems like it should work and the port is also working.
I tried using a variety of servers. The one in the sample code below is taken from https://server.pro/
So, the question is, why doesn't _serverSocket.Accept(); trigger, since the sender can connect and send strings with no errors ?
private static Socket _serverSocket, _clientSocket;
private const int _PORT = 40288;
//this IP doesn't work, but 127.0.0.1 works flawlessly
private static IPAddress _IP = IPAddress.Parse("37.187.143.226");
//---------sender (client) code---------
_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
//connects, no errors appear
_clientSocket.Connect(IPAddress.Parse(_IP), _PORT);
//sends strings to the server, no errors appear
while (true) {
Console.Write("Enter text to send: ");
string input = Console.ReadLine();
_clientSocket.Send(Encoding.ASCII.GetBytes(input));
Console.WriteLine("Sent!");
}
//-------listener (server) code--------
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, _PORT));
_serverSocket.Listen(10);
Console.WriteLine("Waiting for a client socket to connect");
_clientSocket = _serverSocket.Accept(); //never triggers
Console.WriteLine("Socket accepted, waiting for data...");
The server code must run on the machine that you want to connect to. That would be the machine that has IP 37.187.143.226.
So either run everything locally and use target IP "localhost" or run the server on that other box and use the 37 IP.
Also be aware that often firewalls and routers must be configured to allow access.
I have several LANs(10.0.0.x) connected to a WAN(192.168.1.x). Each through a router that allows a network directed broadcast. This is to allow the devices in the LANs to be discovered by devices on the WAN.
I can send a broadcast on the LAN(10.0.0.255) and receive it on my socket. But when I move to the WAN I can see it in wireshark, but not my socket. I other words I have a device with address 10.0.0.1 sending the same message to 192.168.1.255 through a gateway but my socket is not receiving it. When this happens the source address is the address of the router. Here is the code for my socket:
udpSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
//Assign the any IP of the machine and listen on port number 5000
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 5000);
//Bind this address to the server
udpSocket.Bind(ipEndPoint);
IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 5000);
//The epSender identifies the incoming clients
EndPoint epSender = (EndPoint)ipeSender;
//Start receiving data
udpSocket.BeginReceiveFrom(byteData, 0, byteData.Length,
SocketFlags.None, ref epSender, new AsyncCallback(ReceiveAnnounce), epSender);
I have a wireshark trace for each message but I'm not sure the best way to post it. Thanks.
Do you understand that UDP provides no guarantee that a packet will be received? (TCP uses a client to server connection) and that packets are broadcast to a 'multicast group' (this resembles an IP-address but must be in the range 224.0.0.0 to 239.255.255.255) rather than to an IP.
Your use of IPAddress.Any tells it to use all network interfaces, but you never tell it which multicast group to use, I've never done this in C# myself, however it appears you want to add this line of code before your BeginReceiveFrom;
udpSocket.SetSocketOption(SocketOptionLevel.IP,SocketOptionName.AddMembership,new MulticastOption(TARGET_IP));
You should replace TARGET_IP with the address of your multicast group you wish to listen on.
I took that line of code from this site; http://osix.net/modules/article/?id=409
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?
Well, I wonder if some one can help with a problem that I encounter....
I want to close a socket and then rerun from the same port. This is what i am doing...
opening:
UdpServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
UdpServerIpEndPoint = new IPEndPoint(IPAddress.Any, 9050);
UdpEndPoint = (EndPoint)UdpServerIpEndPoint;
UdpServer.Bind(UdpServerIpEndPoint);
closeing:
UdpServer.Shutdown(SocketShutdown.Both);
UdpServer.Disconnect(true);
UdpServer.Close();
After I close it. and the I try to reconnect it with the same code as above, I get error:
Additional information: Only one usage of each socket address
(protocol/network address/port) is normally permitted
I checked for exception during closing, but I didnt get any, i guessed they were closed properly, so actually, what is causing this problem? Please help!
I got answer....
I need to use this after decleration of socket...
socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress, true);
You could look at this 2 ways.
Don't actually Receive whilst your are in your stopped state, just in your BeginReceive, just drop/ignore the data
If you really need to recreate the socket, then don't perform the disconnect on your Server because you haven't actually got a connection. Your disconnect is throwing
System.Net.Sockets.SocketException (0x80004005): A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
For reference, in case anyone else stumbles onto this question but looking for the UdpClient implementation.
int port = 1234;
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
var endPoint = new IPEndPoint(IPAddress.Any, port);
socket.Bind(endPoint);
var updClient = new UdpClient();
updClient.Client = socket;
updClient.Connect(_ipAddress, port);