how can I make a socket connection non-locally? - c#

I tried to search for similar questions but I couldn't since I don't know how to pronounce this question.
My server codes for connection is...
server_Listener = new TcpListener(7778);
server_Listener.Start();
while (true)
{UserSocket user = new UserSocket();
try
{
user.client = server_Listener.AcceptSocket();
}
catch
{
break;
}
if (user.client.Connected)
{
user.server_isClientOnline = true;
this.BeginInvoke((MethodInvoker)(delegate()
{
textBox1.AppendText("client connected\n");
}));
user.server_netStream = new NetworkStream(user.client);
the UserSocket class has a Socket(variable name client), and a netStream (server_netStream) to get to receive and send packet data from clients.
My Question is, this works just fine on local connections, but it doesn't work non-locally.
I tried to access to this server using my laptop, and my friend's, but non of them worked.
Not an error although... but it just couldn't receive the connection.
Are my codes wrong? or are there a new way of getting connection non-locally?

It could be the firewall on your machine or some other issue on your network. You might want to try Wireshark (http://www.wireshark.org/) and see if you can glean any information that way.

Related

C# - Detect public ip adress change, VPN issue

With following code I am able to track public IP changes of my desktop application. This should be able to track if either the public IP changed or the user enabled a VPN to change his public IP. This code is run on application launch and used once again when a check is needed:
public class PublicIP
{
IPAddress last_ip=null;
DateTime timestamp_lastipchange;
public void UpdateIP()
{
List<string> hosts = new List<string>()
{
"https://api.ipify.org",
"https://ipinfo.io/ip",
"https://checkip.amazonaws.com",
"https://wtfismyip.com/text",
"http://icanhazip.com"
};
using(WebClient webclient = new WebClient())
{
foreach(string host in hosts)
{
//Download each string from hosts until an IP could be fetched
try{
var newip = IPAddress.Parse(webclient.DownloadString(service)); //Downloading the string
if(!newip.IsEqual(last_ip) && last_ip!=null) timestamp_lastipchange = DateTime.Now; //Check if the ip changed, if the last known ip does not exists skipp this step
last_ip = newip; //Save last known ip
return;
}
catch { }
}
}
}
}
This approach seems to work pretty well, however during UnitTesting some workflows do not fetch a new IP:
IP change by switching networks: change gets successfully detected
IP changed by provider: change gets successfully detected
VPN was enabled when the application was launched and is then turned off:
change gets successfully detected
VPN was disabled on application start and is turned on during runtime:
change does not get detected. Webclient.DownloadString() still returns the same IP as if the VPN was not enabled.
I am not really sure what is happening in workflow nr 4. Do I have to manually select the new network interface (VPN)? Or is this a caching problem on the client/server side?
WebClient is high-level and might using static pool behind-the-scene (and also deprecated). You might try using HttpClient instead, because HttpClient handle connection via its message handler, and the default one is not static, which means this should work:
using(var httpClient = new HttpClient())
{
var newip = IPAddress.Parse(webclient.GetStringAsync(service)
.ConfigureAwait(false).GetAwaiter().GetResult());
// ...
}

wss WebSocket server in Mono C# : SslStream gives me no data but Stream do

Since days I'm trying to get (JS)wss/(c#)SslStream connection to work in order to create a wss server in mono c#.
My Problem : When an incomming secure WebSocket connection is accepted by the server, I can't get data from it in order to begin the handshake process.
What I did so far :
I setup a TCPListener that accept the client giving me a TCPClient instance.
I get the stream from the TCPClient and create a SslStream from it.
I synchronously authenticate it with AuthenticateAsServer(X509Certificate2)
I unsuccessfully try to read data
Other details :
I note that if I use a Stream object instead of an SslStream one, I succed in getting data from it (but crypted as expected)
I tested to connect my WebSoket to same adress/port to Fleck (built on my box with Monodevelop too) using the same pfx certificate and got it working properly
I note also that Fleck throw messages saying it recieve 0 byte, then it close the connection and (in some way) reconnect it and get data properly from Socket/SslStream.
I don't get any error, SslStream seem to be correctly authenticated
I correctly connect clients in https and deal with requests on an another port in the same program
My Configuration :
OS : ArchLinux
C# : Mono .Net Framework 4.7
Browsers (Chromium & Firefox)
Despite of all my research so far I've not found the solution , maybe someone can help me to wonder what I miss here ...
Thanks in advance for any help !
The listen code :
public void AudioListen ()
{
audioComListener.Start ();
while (isAudioActive) {
TcpClient s = audioComListener.AcceptTcpClient ();
Stream clientStream;
string hellostr;
clientStream = getClientStream(s);
if(debugCommuncation)
{
logToFileLine("(KEY) HandShaking begins with "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
}
if(!WebSocketHandshake(clientStream))
{
if(debugCommuncation)
{
logToFileLine("(KEY) (X) HandShake read 0 byte from "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
}
s.Close();
return;
}
else
{
logToFileLine("(KEY) HandShaking OK with "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
}
hellostr=streamReadLine(clientStream);
if(hellostr.IndexOf("hello:")==0)
{
string usrstr=hellostr.Split(':')[1];
User usr= Users.GetUser(usrstr);
if(usr!=null)
{
usr.TcpC=s;
User usrdest=usr.corresp;
if( usrdest!=null &&
usrdest.ByPass==null &&
usrdest.TcpC!=null)
{
Stream clientStream2 = getClientStream(usrdest.TcpC);
usr.ByPass=new TCPByPass(clientStream,clientStream2);
usrdest.ByPass=usr.ByPass;
}
}
}
Thread.Sleep (1);
};
}
Function to get the SslStream :
private Stream getClientStream(TcpClient s,bool forceHTTP=false)
{
Stream clientStream;
if(isSSL && !forceHTTP)
{
clientStream = new SslStream (s.GetStream ());
((SslStream)clientStream).AuthenticateAsServer(SrvCert);
// Set timeouts for the read and write to 5 seconds.
/**/clientStream.ReadTimeout = 5000;
clientStream.WriteTimeout = 5000;
//SecuDiag.MakeAllDiag(((SslStream)clientStream));
}
else
{
clientStream=s.GetStream ();
}
return clientStream;
}
Function that try to get data for hanshake purpose :
public bool WebSocketHandshake(Stream clientStream)
{
string hellostr;
// Here I test trying to get data (Also tried to use Stream.ReadByte())
Byte[] toto=new Byte[2048];
((SslStream)clientStream).Read(toto,0,2048);
if(toto[0]==0)return false;
Console.WriteLine("#############################################");
Console.WriteLine("toto array is {0} bytes long",toto.Length);
for(int t =0;t<10;t++)
{
for(int u =0;u<10;u++)
{
Console.Write(toto[t*10+u].ToString());
}
Console.WriteLine(";");
}
Console.WriteLine("#############################################");
// Trying to get data
//hellostr=streamReadLine(clientStream);
//Console.WriteLine(hellostr);
return true;
}
I think I solved the problem. I don't understand why, but I think its necessary to close the accepted connection just after accepting it iaoi the connection is wss. The the websocket wil automagically reconnect :)

How to use MaxReconnectAttemps in ActiveMQ

I'm having an issue with ActiveMQ, I'm trying to connect using MaxReconnectAttemps but its seems to ignore the property. I'm putting an invalid destination so it tries to connect twice but it seems to be trying to connect indefinitely.
Any ideas as to set it up?
Thanks,
IConnectionFactory factory = new ConnectionFactory(("failover://(tcp://localhost:61616)?initialReconnectDelay=2000&maxReconnectAttempts=2"));
using (Connection connection = factory.CreateConnection(username,password) as Connection)
{
connection.ClientId = "ClientId";
using (ISession session = connection.CreateSession())
{
IQueue queue = session.GetQueue(queueName);
var producer = session.CreateProducer(queue);
producer.DeliveryMode = MsgDeliveryMode.Persistent;
ITextMessage request = session.CreateTextMessage("Hello World!");
producer.Send(request);
}
}
Since you are using the .NET client you need to use a prefix on the URI options for the failover transport, so to configure maxReconnectAttempts you need to pass the option like this:
failover:(tcp://localhost:61616)?transport.maxReconnectAttempts=3
It's a good idea to look at the documentation for the client you are using which is here.

Odd behavior using the IBM DB2 for i5/OS .NET provider dll in C#

At my company we use the IBM DB2 for i5/OS .NET provider dll version 12.0.7.3. in a web application that makes database calls to the iSeries. We encountered a situation where a method which would create a connection then pass that connection to subroutines would seem to access the wrong data sometimes. An example case is as follows: Assume the server has just spun up. Client A calls the "GetContractPdf" and it succeeds. Client B then calls the same method and it fails. The server is restarted and Client B calls the "GetContractPdf" method which then succeeds. Client A calls it and it fails.
I pulled my hair out trying to figure this out but it appears that the code isn't disposing of or handling the database connections properly. It is reproducible in my development environment and when I do reproduce it the connection object shows the right library list for the client that I used to call it, but after inserting a test query that would yield data that could easily identify the client database being touched it was absolutely getting the wrong data. The databases in question are running on the same physical AS/400 machine with different library lists. A third client who has their own AS/400 is unaffected by this problem.
I have been changing any method that accepts a connection as an argument to create their own connection and hoped that it won't cause too big of a performance hit.
Here is the method that generates the connections:
public static iDB2Connection GetConnection(string ClientCode)
{
string decrypted = "";
try
{
decrypted = System.Configuration.ConfigurationManager.ConnectionStrings[ClientCode].ConnectionString;
}
catch (Exception)
{
throw new FaultException(string.Format("Client connection string not found for {0}.", ClientCode));
}
try
{
decrypted = EncryptDecrypt.Decrypt(decrypted);
}
catch (Exception)
{
throw new FaultException(string.Format("Error determining connection string for client {0}.", ClientCode));
}
try
{
return new iDB2Connection(decrypted);
}
catch (Exception)
{
throw new FaultException("Error accessing database.");
}
}
And here is some pseudocode that shows how it is used when the problem behavior arises:
public static ContractObject GetContract(clientCode,contractId){
using(iDb2Connection conn = GetConnection(clientCode)){
ContractObject contractObject = new ContractObject(){
Id = contractId
};
GetSomeData(contractObject,conn);
GetOtherData(contractObject,conn);
return contractObject;
}
}
public static void GetSomeData(ContractObject contract, iDb2Connection connection){
string commandText = "Select data from table where conditions";
using(iDb2Command cmd = new iDb2Command(commandText,connection)){
using(iDb2DataReader reader = cmd.ExecuteReader()){
if(reader.HasRows){
contract.Foo = reader["ColumnName"].ToString();
}
}
}
}
public static void GetOtherData(ContractObject contract, iDb2Connection connection){
string commandText = "Select data from table where conditions";
using(iDb2Command cmd = new iDb2Command(commandText,connection)){
using(iDb2DataReader reader = cmd.ExecuteReader()){
if(reader.HasRows){
contract.Bar = reader["ColumnName"].ToString();
}
}
}
}
If I change the methods up so that a new connection object is created for every query the behavior is eliminated.
As I see it there are two possible problems, either I have done something horribly wrong (which I certainly could have), or the IBM dll does not handle passing around connection objects well (which you would think is less likely but could happen). I'm sure there are other possibilities that I'm too inexperienced / code blind to see.
Do any of you have any ideas of what could be causing this behavior or questions that could lead us to figuring out what causes this behavior?
Thanks in advance for your time.

Check Load Balancing server using C#

I have four application server for my application.Application is working on all server using load balancing.If one of my server goes down I have to check it manually using my system hosts file.To avoid this manual process I have created one program using C#.I write server IP address one by one in host file and remove previous one.
private void RunWithUAC()
{
List<string> lstIPAddress = new List<string>();
lstIPAddress.Add("1.1.1.1 example.com");
lstIPAddress.Add("1.1.1.1 example.com");
lstIPAddress.Add("1.1.1.1 example.com");
lstIPAddress.Add("1.1.1.1 example.com");
var systemPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
Console.WriteLine(systemPath);
var path = #"C:\Windows\System32\drivers\etc\hosts";
foreach (var item in lstIPAddress)
{
System.IO.File.WriteAllText(path, string.Empty);
try
{
File.WriteAllText(path, item);
WebRequest request = WebRequest.Create("https://example.com");
request.Timeout = 10000;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
}
catch (Exception)
{
MessageBox.Show(item);
}
Thread.Sleep(1000);
}
}
But When second server goes down.It will give me timeout error for third server.
Please check the code and let me know what is wrong with this code.
Probably some kind of connection pooling, HTTP pipelining or keep-alive. This is the wrong approach in the first place.
Connect directly to the right IP (WebRequest.Create("https://1.1.1.1")). If you need to send a Host header add that manually to the request.

Categories

Resources