VS 2008
I am using the code below to detect if the client can connect to our SIP server. This was working fine. However, the client has changed there network and now my application has to connect to the SIP server from behind a proxy server.
The error I get is the:
"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 xxx.xxx.xx.xx:xx"
This code was working ok, until I have to connect from behind a proxy server.
I could not see any properties there I can add the proxy address to the socket.
Am I missing something?
Many thanks for any suggestions,
public bool IsSIPServerAvailable()
{
bool isAvailable = true;
Socket sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
try
{
sock.Connect("xxx.xxx.xx.xx", xx);
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
isAvailable = false;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
isAvailable = false;
}
finally
{
if (sock.Connected)
{
sock.Close();
}
}
return isAvailable;
}
See my answer here, maybe it will be helpful. The general idea is to first establish connection to a proxy, and then use HTTP CONNECT command to open another TCP connection to a given host and port.
This is very similar to this question. I don't think it is possible to create a socket connection through a proxy server. You would need some kind of a protocol and more over, usually administrators set up proxy servers to refuse connections from ports other than standard HTTP, HTTPS.
One solution would be to use tunneling over HTTP.
The whole idea of a proxy is to change the network topology without changing the applications. Thus there is no need to change the app, but a change is required in the proxy configuration/setup.
To check the proxy config independently of your application, you can use Telnet Host Port and see if you get the same timeout/error message or if you get disconnected after entering a few characters.
Related
I have a c# socket server started on a windows server pc.
This is the code that make the server start :
appServer = new AppServer();
var m_Config = new ServerConfig
{
Port = 3000,
Mode = SocketMode.Tcp,
Name = "zonedetecserveur",
TextEncoding = "UTF-8"
};
//Setup the appServer
if (!appServer.Setup(m_Config))//Setup with listening port
{
Console.WriteLine("Failed to setup!");
Console.ReadKey();
return;
}
//Try to start the appServer
if (!appServer.Start())
{
Console.WriteLine("Failed to start!");
Console.ReadKey();
return;
}
Console.WriteLine("The server started successfully, press key'q' to stop it!");
This code works on the windows server pc, and the server start properly with the message "The server started successfully, press key'q' to stop it!"
But, when I try to reach the server by using :
//Create an instance
SocketClient = new Socket(SocketType.Stream, ProtocolType.Tcp);
IPAddress _ip = IPAddress.Parse(ip);
IPEndPoint point = new IPEndPoint(_ip, 3000);
//Make connection
SocketClient.Connect(point);
The application just crash with the error
System.Net.Internals.SocketExceptionFactory.ExtendedSocketException : 'A connection attempt failed because the connected party did not respond appropriately beyond a certain duration or an established connection failed because the connecting host did not respond. [::ffff:MY_SERVER_IP]:3000'
What I have done :
Open the port 3000 on my internet router so it can be receiving tcp things
Disable the firewall for the server.exe (it's basically the code I showed you on a cmd)
Trying different port
Note that when I put as an ip 127.0.0.1 and I start the server on my pc and send data to this ip it works perfectly fine.
Any help on why my server says it started but does not exist is appreciated.
Thank you
Again, I need invaluable help of you.
I have project set up using HttpListener class to bind and listen on all found IPs and port(in this example) 1337.
Now, local connections(from my own computer typing IP:Port into address bar from browser) work just fine, but any connection from remote devices, even in the same wifi network, just don't hit listener.
Example code(instead of all found IPs I listen to all connections at port 1337)
HttpListener httplistener = new HttpListener();
httplistener.Prefixes.Add("http://+:80/");
httplistener.Start();
HttpListenerContext ctx = httplistener.GetContext();
Console.WriteLine("got context");
ctx.Response.OutputStream.Write(Encoding.ASCII.GetBytes("hello"), 0, 5);
Console.WriteLine("response written");
ctx.Response.Close();
Console.WriteLine("response closed");
Console.ReadKey();
Well, from any browser I get response as it should be(and under normal circumstances I use it I get JSON object for my JS app), but from any device in wifi network I got timeout and I never got even to the context.
TcpListener on the other hand works properly. Why? I know the difference more or less and in TcpListener I can get a raw connection(like from Putty):
TcpListener tcplistener = new TcpListener(endpoint);
tcplistener.Start();
TcpClient tcpclient = tcplistener.AcceptTcpClient();
int dataAvailable = tcpclient.Available;
Console.WriteLine("connection accepted");
using(StreamWriter sw = new StreamWriter(tcpclient.GetStream()))
{
sw.WriteLine("<html><body>hello</body></html>");
}
Console.WriteLine("response written");
tcpclient.Close();
Console.WriteLine("waiting for next connection");
Is it possible to somehow use HttpListener anyway or route connections to it? I really need possibility to connect to my app from every device through a html page. For any advices thank you. Tag #windows-phone-8.1 added because tried to connect from that device to HttpListener too with no positive effect.
Ok, case closed. After exhausting every possible option, sniffing packets revealed that send packets are lost in translation and never get to my computer where server is started. I pushed on IT and they declined everything but after confronting with hard evidence they had to yield and admit that someone made this specific subnetwork work in a way that separates every client from each other.
So, when I manually opened a socket I was able to connect(and sometimes not, but I thought it was just my wrong and messy implementation) but every other piece of traffic was mowed down before getting a chance to arrive at my network card.
I am working with an application that receives a file by a TCP protocol, the application processes the file and then sends it by the same protocol, i am receiving the file without problems, my problem is when i try to send the file, because i need to send the file to another application that is listening a Dynamic port, the code that i am using to send these files is:
internal void Send(byte[] buffer)
{
TcpClient _client = null;
try
{
_client = new TcpClient(RemoteIPaddress, Dynamic_port);
if (_client != null)
{
NetworkStream _clienttStream = _client.GetStream();
_clienttStream.Write(buffer, 0, buffer.Length);
_clienttStream.Flush();
_clienttStream.Close();
_clienttStream = null;
}
}
catch
{
if (_client != null)
{
_client.Close();
_client = null;
}
}
}
The question is, how can i send a file by TCP protocol to a remote machine that uses a dynamic port
Typically, the server should listen on a well known port for a connection request. The response should include the port number that the server will communicate further on. Then your app connects to that port for transferring the data.
The communication should do the following:
Client connects to server on well known port.
Server responds with the dynamic port number to use for further communication.
Client connects to server on the received port number.
Server responds stating connection established.
Client transmits data and disconnects.
This is a simplified version of how passive FTP works.
Point is, there are only two ways to connect to a server on a dynamic port. The first way is outlined above. If you can't do it that way then your client app will have to do a port scan, sending a connection attempt to every port within a range, and see which one the server responds on. However, firewalls are generally programmed to notice this type of thing and shut you down (it's hacker behavior).
Are you asking how you can determine the dynamic port that the remote machine has selected to use? There is no automated way to do this. The server should either work on a port that both machines are aware of or you should work out a way for them to select a port through some other mode of communication. Either by connecting to a 3rd party server or hosting a web service that the client can access.
I have the following setup:
Dedicated server --> Internet --> Modem (telenet) --> Router --> client
The client initiates a tcp connection with the server to register itself on the server, and gives through following info:
mac address of the client
external ip; this is retrieved by using webclient string download from whatsmyip.org
Some updates occur on the server and of course the client needs to be notified, so the client can start a sync session on its own:
To notify the client, the server sends a udp packet from the server to the modem (to the external ip, earlier received from the client), in the meanwhile the client is listening for udp packets behind the router.
The problem is that I'm not receiving any packets.. Is my scenario possible, what should I do?
Requirements:
Solving this by enabling port-forwarding on the router isn't an option
The server has a fixed ip
The client can be disconnected from the internet, at times
The solution has to work on different kinds of routers
Both ports at which packets are send & received are the same
All programming is done in C#
The server notifies the client when there is an update, the client may never poll the server for updates to prevent overload (in case several clients are doing this the same time)
Greets Daan & thanks in advance
EDIT:
Code example from server:
UdpClient udpSender = new UdpClient();
IPEndPoint localServerGateway = new IPEndPoint(IPAddress.Parse(externalIp), 8003);
string message = "testmessage";
byte[] messageBytes = Encoding.ASCII.GetBytes(message);
try
{
udpSender.Send(messageBytes, messageBytes.Length, localServerGateway);
}
catch (Exception error)
{
Console.WriteLine("Error while sending message: " + error.ToString());
}
udpSender.Close();
Code example from client:
private void listenForMasterSyncRequest()
{
bool done = false;
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 8003);
try
{
while (!done)
{
byte[] bytes = masterSyncUdpListener.Receive(ref groupEP);
handleMessage(bytes, bytes.Length, true); // handles incoming messages, this is never reached because no packets are received :-(
}
}
catch (Exception e)
{
Console.WriteLine("An error occured while listening to server broadcast updates: " + e.ToString());
}
finally
{
masterSyncUdpListener.Close();
}
}
NAT works by setting up sessions between external and internal hosts. But the session must be initiated on the internal side, and in your case that's the client side. So the way it has to work is that the client has to poll the server, sending a UDP packet to a particular port on the server asking if a sync is needed. The server must send a UDP response from that same port back to the same port the client sent the original request. If you do it this way packets from the server will get through, otherwise they will not. I know this works because this is exactly how DNS lookups work from behind NAT.
Since you don't have control of the NAT devices in the path, the only sane way here is to use TCP as your main transport.
I can run the server on my local machine and connect to it on the same machine, but when I try to connect to it from a different computer over the internet, there is not sign of activity on my server, nor a response from the server on the computer I'm testing it on. I've tried both XP and Vista, turn off firewalls, opened ports, ran as admin; nothing is working. :(
Here is my code that I'm using to accept an incoming connection:
int port = 3326;
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Any, port));
listener.Start();
Console.WriteLine("Server established\nListening on Port: {0}\n", port);
while (true)
{
socket = listener.AcceptSocket();
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, outime);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.DontFragment = true;
NewConnection pxy = new NewConnection(socket);
Thread client = new Thread(new ThreadStart(pxy.Start));
client.IsBackground = true;
client.Start();
}
}
I think that the problem is in your router, not your computer. When packets come from the Internet, it should be routed to an specific server. You have to configure your router to redirect the traffic on port 3326 to your server.
You've probably got something blocking the connection higher up. Try connecting from another host on the LAN. If you can do that, then the OS itself isn't firewalling the connection.
If either you or your ISP run a NAT router, then your machine probably doesn't have a publicly accessible address, in which case it's impossible to connect directly to it.
If there is no NAT router, something may still be blocking the connection upstream.
I am serious: Many ISPs actively work to stop you from using your home connection as a web server. You might want to call them before you invest too much time.
If you are trying to host at home, your ISP may be restricting you.