Socket can connect to server on WIFI, but not with cellular data - c#

I have a 100 clients that connect to my server using websockets (now tcp). My code is very simple (see below). I have a client on T-Mobile 4G Data using a OnePlus 5t that is not able to connect to the server on mobile data, yet he can on wifi data. Any idea what could be the problem? I must note that I am using .netstandard 2.0 also.
What I have tried so far:
User has checked that the app has permission to use mobile data.
I have changed the protocol to use 'wss' instead of 'ws'.
I have changed the port (user checked https://www.websocket.org/echo.html and it said he was able to connect to it).
Finally, (a few weeks later) I have switched everything to a tcp client protocol and this still did not work.
None of these options have thus far worked.
public void Connect(string address, int port)
{
UriBuilder uriBuild = new UriBuilder("ws", address, port);
Uri uri = uriBuild.Uri;
_ws = new ClientWebSocket();
_tokenSource = new CancellationTokenSource();
ConnectToServerAsync(uri);
}
private async void ConnectToServerAsync(Uri uri)
{
await _ws.ConnectAsync(uri, _tokenSource.Token);
}

Related

Why doesn't Microsoft.Azure.ServiceBus's QueueClient drop back to HTTPS? [duplicate]

I have created a very simple console application that connects to Azure ServiceBus and sends one message. I tried the latest library from Microsoft (Microsoft.Azure.ServiceBus) but no matter what I do I just get this error:
No connection could be made because the target machine actively
refused it ErrorCode: ConnectionRefused
I have tried exactly the same connection string in Service Bus Explorer and it does work just fine. Moreover I connected without problems using the older library from Microsoft (WindowsAzure.ServiceBus).
var sender = new MessageSender("endpoint", "topicName");
sender.SendAsync(new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject("test"))));
I tried with .NET Framework 4.6.2 and Core, same exception. I suspect there may be some differences in the default protocol that these libraries use, but I could not figure out that for sure.
P.S. Have tried the example from Microsoft docs but result is still the same exception
The old client supported ConnectivityMode using TCP, HTTP, HTTPS, and AutoDetect. ServiceBus Explorer is using AutoDetect, trying TCP first and then failing over to HTTPS, regardless of the TransportMode you were using (SBMP or AMQP).
With the new client this has changed. TransportMode now combines both options and offers Amqp (AMQP over TCP) or AmqpWebSockets (AMQP over WebSockets). There's no AutoDetect mode. You will have to create your clients and specify TransportType as AmqpWebSockets to bypass blocked TCP port 5671 and instead use port 443.
It seems that the documentation is lacking a lot on how to connect using HTTPS (Amqp over WebSockets) but after some help from Sean Feldman in the accepted answer I managed to connect. Here is the code that I used if someone is interested:
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
"RootManageSharedAccessKey", // SharedAccessKeyName
"SomeToken");
var sender = new MessageSender(
"sb://mydomain.servicebus.windows.net/",
"topicName",
tokenProvider,
TransportType.AmqpWebSockets);
Or a variant that let's you have the whole connection string in one piece
var builder = new ServiceBusConnectionStringBuilder("YouConnectionString");
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
builder.SasKeyName,
builder.SasKey);
var sender = new MessageSender(
builder.Endpoint,
"TopicName",
tokenProvider,
TransportType.AmqpWebSockets);
It is actually possible to use ConnectionString directly but then it has to be augmented to use the right protocol.
var sender = new MessageSender("TransportType=AmqpWebSockets;Endpoint=...", "TopicName")
Or the version that allows to embed EntityPath into the ConnectionString
var connectionBuilder = new ServiceBusConnectionStringBuilder("EntityPath=MyTopic;TransportType=AmqpWebSockets;Endpoint=...")
var sender = new MessageSender(connectionBuilder);
I was having the same issue but his worked for me
var clientOptions = new ServiceBusClientOptions();
clientOptions.TransportType = ServiceBusTransportType.AmqpWebSockets;
client = new ServiceBusClient(connectionString, clientOptions);
sender = client.CreateSender(topicName);
// create a batch
using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

LDAPS connection with ASP.Net/C#

I have a connection string for LDAP protocol
ldap://ldap.example.com:636/DC=users,DC=buyers
which works fine.
But I need to use a LDAPS connection :
ldaps://ldap.example.com/DC=users,DC=buyers
which does show up in ldp.exe windows form when I test the connection.
Unfotunately it does not work in the Asp.Net application. I get "Unknown error (0x80005000)".
I am not sure whether LDAPS string is even possible with Asp.Net. I downloaded the source code into LDAPConnection.cs class and was unable to find any valuable information.
The method you found that works is indeed using LDAPS:
ldap://ldap.example.com:636/DC=users,DC=buyers
That's the only way to do it. I do that in one of my existing projects. It doesn't understand "LDAPS://".
If you don't believe me :) fire up Wireshark as you debug. When it connects, you'll see the SSL handshake to your domain controller.
Port 636 is only for LDAPS. Port 389 is the non-SSL port.
If you have more than one domain, you can use port 3269 for the global catalog via SSL.
Below code worked for me to connect to AD using LDAPS
ldapConnection = new LdapConnection(new LdapDirectoryIdentifier("your.LDAPSserver.com", 636));
var networkCredential = new NetworkCredential("UsernameWithoutDomain", "yourPassword", "AD.yourDOMAIN.com");
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.SessionOptions.ProtocolVersion = 3;
ldapConnection.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(ServerCallback);
ldapConnection.AuthType = AuthType.Negotiate;
ldapConnection.Bind(networkCredential);
SearchRequest Srchrequest = new SearchRequest("CN=Users,DC=AD,DC=YOURCOMPANY,DC=COM", "mail=useremail#company.com", System.DirectoryServices.Protocols.SearchScope.Subtree);
SearchResponse SrchResponse = (SearchResponse)ldapConnection.SendRequest(Srchrequest);
// ServerCallback
private static bool ServerCallback(LdapConnection connection, X509Certificate certificate)
{
return true;
}
Surprisingly it is also working when I am not using networkCredential and just using ldapConnection.Bind(); Seems it is using my local credentials as default on my local machine.

How to use TCP Client in Android without Sockets?

I have a TCP server in C# and also a TCP Client in C#, now I need a TCP Client in Android too.
All the examples i found are related to sockets, but I'm using a simple TCP Client so they don't work.
Right now my C# TCP Client is like that:
TcpClient client = new TcpClient("127.0.0.1", 1200);
NetworkStream n = client.GetStream();
Console.WriteLine("Insert name");
string name= Console.ReadLine();
byte[] message = Encoding.Unicode.GetBytes(name);
n.Write(message, 0, message.Length);
Is there a corresponding of this function in Android?
This is the actual android client i'm trying and that doesn't work
InetAddress serverAddr = InetAddress.getByName("127.0.0.1");
socket = new Socket(serverAddr, 1200);
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
First, this line:
InetAddress serverAddr = InetAddress.getByName(127.0.0.1);
contains a syntax error. It should be:
InetAddress serverAddr = InetAddress.getByName("127.0.0.1");
Second, the address "127.0.0.1" refers to the "same machine" that executes the client. In the case of your C# program, the server runs on the same machine as the client, so it worked. But in the case of Android, there in no server that runs on the "same machine", which is your Android phone (event if it is emulated, 127.0.0.1 refers to the emulated Android device, not the PC that it works on). You must specify a "good" address to the Android device that refers to the machine on which the server executes.
So, the problem is not in using sockets.
You can simply connect to your server using this line, also try to disable your firewall if your server is running on your PC.
Socket server= new Socket("192.168.1.1", 4444); // Enter your PC/Server IP address in place of 192.168.1.1

Nodejs Express + Socket.io + client on C#

i just don't understand why simple socket.io part don't work.
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(3000, function(){
console.log('listening on *:3000');
});
app.use(function(req, res, next) {
console.log("INIT");
console.log(req.headers['user-agent']);
console.log(req.ip);
next();
});
app.use('/', routes);
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
This is my cliend side code at C#. So when my nodejs server is online i don't get any errors from C#, so it's connecting, but i don't see it at node console.
And this must work, i get this example here - https://www.youtube.com/watch?v=nwV3MS6pryY
using System;
using System.Net.Sockets;
namespace TCPSocketConsole
{
class Program
{
static TcpClient mySocket = new TcpClient();
static void Main(string[] args)
{
mySocket.Connect("127.0.0.1", 3000);
Console.ReadLine();
}
}
}
So when i connect to http://localhost:3000 i don't get "a user connected" at my console.
You are listening for a socket.io connection on your server, but your client is just make a plain TCP connection. The two protocols on each end must be the same. socket.io is not a plain TCP connection.
You can either listen for a plain TCP connection on your node.js server (and thus invent your own protocol) or you can get a class for a socket.io connection in your C# client so your C# client can actually speak to a socket.io server properly.
socket.io is based on webSocket and webSocket has a whole protocol for establishing the initial connection (it starts with an HTTP connection that is then upgraded to a webSocket connection) and then both webSocket and socket.io have their own framing for how data is sent. Both ends of the connection must speak the same protocol.
In the socket.io docs you have an example of the client and server side. It seems your are not connecting from client side.

How to know "The DNS name of the remote host" of a computer?

I have two programs use to communicate with each other via UDP protocol (client and server), but when the client connects to the server using the method Connect (
string hostname,
int port
), Nothing happened.
This is code:
udpclient.Connect("asuspc",6500);
string duongdan = tbduongdan.Text;
Byte[] sendbyte = Encoding.ASCII.GetBytes(duongdan);
udpclient.Send(sendbyte, sendbyte.Length);
"asuspc" is name of computer that i intend to connect.
After a while to find out, I know that the hostname is "The DNS name of the remote host" rather than the name of computer, then what is "The DNS name of the remote host"?How to know "The DNS name of the remote host" of a computer?
By definition, UDP is a connection-less protocol. You do not need to connect in order to send/receive data.
Note that calling Connect() on a UdpClient object does nothing other than setting a default remote host so that you won't have to specify it each time you use the Send method. So don't expect anything to "happen" after the client calls the Connect method.
With that out of the way, if both your server and your client are on your private LAN, why don't you use the computer's IP? e.g.
// replace 192.168.1.44 with the server's private IP
udpclient.Connect("192.168.1.44",6500);
string duongdan = tbduongdan.Text;
Byte[] sendbyte = Encoding.ASCII.GetBytes(duongdan);
udpclient.Send(sendbyte, sendbyte.Length);
Uhm... I think that a bit of TCP/IP reading will help you a lot :-)
Every machine has an assigned IP address. To not have to remember those long IP addresses, DNS servers were created, so you can write "host.domain.com", and your DNS servers tells you that this "machine DNS name" corresponds with the IP address xx.xx.xx.xx.
Said that, to know the "DNS name" of a machine, under windows (and linux) you can write:
nslookup ip_address_of_the_machine
Example: nslookup 192.168.1.2
Hope that helps.
In server side, (code to get ip address only)
// get the ip and port number where the client will be listening on
static IPEndPoint GetClientInfo()
{
// wait for client to send data
using (UdpClient listener = new UdpClient(6500))
{
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 6500);
byte[] receive_byte_array = listener.Receive(ref groupEP);
return groupEP;
}
}
Then to get IP
var ip = clientInfo.Address.ToString();
var port = clientInfo.Port;
UdpClient client = new UdpClient(new IPEndPoint( IPAddress.Any, 6500));
client.Connect(ip, port); // use ip address
Then in client side you can recieve the data using the buffer

Categories

Resources