remote socket listener - c#

I have a question.
I would like to create a socket listener, but the listen address is from a remote server.
So say SERVER A has the socket listener.
SERVER B (ex. IP = 123.456.78.23:1970) has the listen port.
If I create the socket like this (and execute it on server A):
IP EndPoint endpointIp = new IPEndPoint(123.456.78.23, 1970);
this._socket = new Socket(endpointIp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
this._socket.Bind(endpointIp); // crashes here
this._socket.Listen(MaxPendingConnections);
The program crashes on the Bind code: "The requested address is not valid in its context".
How can I listen on a remote port?
Thank you!

You can't listen to a port on one computer from another. (Hence the message "not valid in this context")
What you CAN do is write one program/service that runs on SERVER B and listens to the port, and use Remoting or WCF to write ANOTHER program that runs on SERVER A that monitors your service on SERVER B rather than trying to listen on a port on SERVER B.

You can't open a socket using an IPEndPoint (basically IP and port) of a different server. What you are asking about is server spoofing - pretending to be a different server and receiving the traffic addressed to it. You will need to configure server A to have the IP of server B, and make sure every router on the way to it can reach server A with this IP.
Edit: Following your comment on the original question, what you need is a load balancer. In order to allow for server B to take over when server A is dead, you must have a router or a server that receives all traffic and directs it to server A, then if it senses that server A is down will redirect all traffic to server B. Of course since you already are doing load balancing, might as well make it a real load balancer, forwarding the traffic to both servers while both are up, and to the remaining one when the other one fails.

Related

Can you run a client application and a server application on the same host machine

I have a synchronous TCP server and client application the works absolutely fine on two separate host machines.
What I'd like to know is what IP and port do I bind the server socket and the client socket to when the applications are both running on the same host machine.
I can't find any solid information on Google about this.
When I try and use my network IP which was 192.168.0.32 I get an error that says the Host actively refused the connection.
I cannot find any reasonable information about this error.
Can I listen and send on the same Port?
What IP address should I use to bind the server and the client, when both applications are running on the same machine?
Thanks for your time.
In order to run both client and server applications on the same host you should bind your server socket to localhost (you can actually write "localhost" it's a preserved word or 127.0.0.1 ) and address it from the client as well.
Localhost allways refers to the computer you work on.
If you'd like to access your server from a machine which is outer to your local network using your network ip you've mentioned, you should first search for "IP FORWARDING" option in your router settings and forward incomming requests to the machine where the server is running on.
Or (my favourite) use the great IP TUNNELING service of ngrok. You can find it here https://ngrok.com/
good luck.
So the answer to this question is that I must bind to my loop back address with separate ports for the client and the server !!
The IP address could be the loopback 127.0.0.1 for both, or your IP address, I don't see why it would not work.
The port on the other hand has to be the same for it to work, assuming the client application doesn't also listens to the port that you "bind" it to.
You have to tell the server on which port it should listen. The client then has to send data on the same port for the server to get the information.
This example should get you going: https://www.codeproject.com/Articles/1415/Introduction-to-TCP-client-server-in-C

C# TCP Listen and Connect on the same Local Port

I have a C# Console Application where I'm trying to implement TCP Hole Punching.
I need to listen on a Local Port and at the same time (simultaneously/asynchronously) connect to 2 different remote hosts (in reality a remote hosts public and private endpoints) using the same Local Port.
As I understand I somehow need to bind the Sockets/Ports but I can't figure this out in C#.
There's the TCPListener, TCPClient and Socket classes and I don't know which ones to use to accomplish what I need.
I'm following this guide http://www.bford.info/pub/net/p2pnat/index.html Chapter 4.2
From the same local TCP ports that A and B (Clients) used to register with (Server) S, A and B each asynchronously make outgoing connection attempts to the other's public and private endpoints as reported by S, while simultaneously listening for incoming connections on their respective local TCP ports.
I've already implemented the server part using NodeJS and it's working fine, I'm struggling with the Local Port stuff mentioned above.
I'm pretty sure that TCP only allows a 1-2-1 connection between client and server and ports. The only way to setup the multiple connections is to create two different sockets.
The TCP hole punching you're referring too I have tried before. You need to basically use the relay server to tell both A and B how to connect.. So do as follows:
1) Client A connects to Server on one port
2) Server tells Client B your IP and the port (this will be a new connection you will be setting up, different to your connection to the server)
3) Server tells Client A the IP and Port that Client B will be using
4) Client A uses the info provided to create a new connection directly to client B
5) Client B uses its info about your "new" connection to try and accept the incoming request
6) It might fail to handshake a couple of times due to latency, so build in some sort of repeater to keep trying the connection
7) You eventually should have a direct connection to B

C# - Socket router for passing sockets to multiple socket servers

is it possible to have one socket router that would pass incoming sockets to socket servers?
I need this because I want to have multiple servers for handling sockets but only one port for clients to connect to. so if one of the servers goes down, router would send the socket to other healthy socket servers.
Is this even possible and how? or any other solution for my problem?
Yes this is definitely possible, and is used very widespread.
Basically you need to have one TCP server running on that one port you want clients to connect to. Then you can listen for connections. When a connection is established you can reroute packets to other servers (you choose).
Listen on a port with your main server
Accept connections as they come in.
When a connection is opened, read the data in another thread. Take that data and send it to the other server you want to.
Basically, it is a proxy.

Connecting to Server on One Computer from another with TCP Listener/Sockets

I have a simple server I can run on one computer that a simple chat client can connect to. When I run the server on my local, I can connect to it fine from a client also on the local. The problem is that I can't seem to connect to the server from a client on another computer.
Some example code from the client:
static string ipAddr = "<server local IP address>";
static Int32 port = 4296;
static System.Net.Sockets.TcpClient tcpClient = new System.Net.Sockets.TcpClient();
tcpClient.Connect(IPAddress.Parse(ipAddr), port);
The remote client hits an exception on that last line. The specific error:
An unhandled exception of type 'System.Net.Sockets.SocketException occurred in System.dll
Additional information: 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.
The server is creating a connection in a similar fashion, on the same port, but on the localhost IP 127.0.0.1, for reference.
I have tried forwarding the port on my router (TCP), as well as opening the inbound and outgoing ports for TCP in my Firewall (I know this isn't sustainable -- just trying to get it working at the moment).
I am pretty confident the issue is that the remote client cannot see the server, but doing a netstat on the port indicates it is listening when the server is running, and is running when the local client is connected. Checking the port through Canyouseeme does actually say that the port is not open, so have I just somehow forwarded the port incorrectly?
Any advice? Thanks very much!
The server is creating a connection in a similar fashion, on the same port, but on the localhost IP 127.0.0.1, for reference.
The server is bound to the loop-back address. Hence when you connect from client running from same machine as server, connect is successful. If the client is external to server's machine, it cannot connect to server on 127.0.0.1 in the other machine.
Bind the server to a valid IP address, reachable from client.

About C# UDP Sockets

I am supposed to connect to external server using UDP sockets in C#..
I could not understand these 2 lines in server usage notes:
"Use of dedicated sockets is enforced."
and
"If the server looses UDP connectivity with the client, it will ..."
I thought that the UDP socket is connectionless!
So what did "looses connectivity" mean? and how to avoid it?
Does there is a known way to ensure "dedicated sockets"?
Thanks
"Use of dedicated sockets is
enforced."
To me this says, create one unique socket for each connection and use it throughout that connection.
EDIT: Just to expand on this, from the servers point of view.
UDP sockets are not identified by the
remote address, but only by the local
address, although each message has an
associated remote address. (source).
That way the server can distinguish from which client each message came from. Because the remote address is made up of an ip address and port combination, you should use the same socket throughout your communication of the sever. This is because if you don't, it's possible you could get assigned a different port next time you change the underlying socket.
"If the server looses UDP connectivity
with the client, it will ..."
It is possible to loose UPD connectivity e.g. either of the endpoints in the connection is lost, say I go to the server and pull the plug?
EDIT2:
Dan Bryant makes an excellent point in the comments, that links in with what I was saying about.
One thing worth noting is that it's
possible for a call to a UDP socket to
throw a SocketException with
SocketError.ConnectionReset as the
error code. UDP does not have any sort
of session with structured
connect/disconnect, but it does use a
dynamically-assigned remote port to
allow replies, which is a kind of
'connection'.
After 2 hours trying different -may be random solutions:
The server wants you to introduce yourself on a port other than the one you will use to actually send data. "dedicated sockets"
You know which IP and Port you are sending start info on, but you do not know which will be used for actual data transmission..
Solution
1- You will create your socket -with known IPEndpoint, and send on it the 'start message'..
2- Then wait to receive from Any IP...
3- The server will response 'welcome message', stating the Endpoint it will use.(by changing parameter ref remoteEP of Socket.ReceiveFrom())
4- You must then change the port you are sending on = remote Endpoint port + 1 (why? standard way or something?)
5- At last you can send and receive normally using these ports

Categories