I have this code, but I don't know if I am well connected or joined to the multicast group. I can send and receive messages through the normal IP "ip". But I don't know if I should do anything more to receive messages through multicast. I have this code:
public void UDPConnect()
{
socket = new UdpClient(25504);
try
{
endPoint = new IPEndPoint(IPAddress.Parse(ip), 2600);
socket.JoinMulticastGroup(IPAddress.Parse(multicastIP));
socket.Connect(endPoint);
byte[] sendBytes = Encoding.ASCII.GetBytes("Hello, from the client");
socket.Send(sendBytes, sendBytes.Length);
ConnectToServer();
}
catch (Exception e)
{
print("Exception thrown " + e.Message);
}
}
public void ConnectToServer()
{
InitializeClientData();
isConnected = true;
StartCoroutine(ClientSend.VisualStartupCor());
socket.BeginReceive(ReceiveCallback, null);
}
public void ReceiveCallback(IAsyncResult _result)
{
try
{
byte[] _data = socket.EndReceive(_result, ref endPoint);
socket.BeginReceive(ReceiveCallback, null);
if (_data.Length < 4)
{
Instance.Disconnect();
return;
}
HandleData(_data);
}
catch
{
Disconnect();
}
}
And this is my server code, just too simple. I just wanna to test if I can send and receive for the Client. As you can see, I have put the multicast IP that I use (231.1.1.10) in the Send method. When I send a message from the client, this server answers by sending the same message to the client. My client, in Unity, detects this message. It means that the multicast connection is successful?
var udp = require('dgram');
// --------------------creating a udp server --------------------
// creating a udp server
var server = udp.createSocket('udp4');
// emits when any error occurs
server.on('error',function(error){
console.log('Error: ' + error);
server.close();
});
// emits on new datagram msg
server.on('message',function(msg,info){
console.log('Data received from client : ' + msg.toString());
console.log('Received %d bytes from %s:%d\n',msg.length, info.address, info.port);
//sending msg
server.send(msg,info.port,'231.1.1.10',function(error){
if(error){
client.close();
}else{
console.log('Data sent !!!');
}
});
});
//emits when socket is ready and listening for datagram msgs
server.on('listening',function(){
var address = server.address();
var port = address.port;
var family = address.family;
var ipaddr = '192.XXX.X.XX';
console.log('Server is listening at port' + port);
console.log('Server ip :' + ipaddr);
console.log('Server is IP4/IP6 : ' + family);
console.log(address);
});
//emits after the socket is closed using socket.close();
server.on('close',function(){
console.log('Socket is closed !');
});
server.bind(2600);
UDP doesn't have a connected status, when you call a JoinMulticastGroup the socket sends a IGMP (Internet Group Management Protocol) packet to the service requesting membership to the multicast group.
If the client is accepted to the group, you can start receiving data on the socket
socket.BeginReceive(ReceiveCallback, null);
Basically there is no way to know if the server is going to send you a message, the point of UDP is to not maintain a connection. You could create a method to ping (send a message) the server and force it to multicast, which sort of looks like what you are trying to do with the "Hello, from the client" message
For more info on multicast groups check out this link
Related
I am implementing mutual authentication.
Client connection has been successfully established.
but getting error "Authentication failed because the remote party has closed the transport stream."
Here is my code :
static void RunClient(string hostName, int port, X509Certificate2Collection certificates)
{
// Create a TCP/IP client socket.
// machineName is the host running the server application.
TcpClient client = new TcpClient(HostName, port);
Console.WriteLine("Client connected.");
// Create an SSL stream that will close the client's stream.
SslStream sslStream = new SslStream(
client.GetStream(),
false, ValidateServerCertificate);
// The server name must match the name on the server certificate.
try
{
sslStream.AuthenticateAsClient(HostName, certificates, SslProtocols.Tls12, true);
}
catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
client.Close();
return;
}
// Encode a test message into a byte array.
// Signal the end of the message using the "<EOF>".
byte[] messsage = Encoding.UTF8.GetBytes("Hello from the client.<EOF>");
// Send hello message to the server.
sslStream.Write(messsage);
sslStream.Flush();
// Read message from the server.
string serverMessage = ReadMessage(sslStream);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Server says: {0}", serverMessage);
Console.ResetColor();
// Close the client connection.
client.Close();
Console.WriteLine("Client closed.");
}
Please help me resolve this issue.
You might be getting this error due to the accepted SSL Protocols versions.
Try changing it to something along these lines:
try
{
sslStream.AuthenticateAsClient(_listenerUri, new X509Certificate2Collection(_serverCertificate), SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, true);
}
I've made a programm, which sends HTTP-webrequests.
To secure these requests being sent, I want to have the ability to define an IP, over which the request should be sent.
So in case of the default exit not working the request should be sent via another exit.
I've tried doing that by using IPEndPoint and Sockets but somehow it's not working.
Here is my Code so far
public Response ExecuteRequest(RequestData requestData, NetworkAddress exit) {
Tracer.Info("Versuche Request über HTTP abzusetzen.");
if (!PrepareIpEndPoint(Address, exit)) {
return null;
}
Address = new Uri(PlaceholderReplacer.ReplacePlaceholders(Address.ToString(), requestData));
return RequestExecutor.ExecuteRequest(Address);
}
private bool PrepareIpEndPoint(Uri url, NetworkAddress exit) {
Tracer.Debug(string.Format("Setze den IP-Endpoint auf{0}", exit));
var ipEndPoint = new IPEndPoint(IPAddress.Parse(exit.Address), 0);
var tempSocket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
tempSocket.Bind(ipEndPoint);
tempSocket.Connect(ipEndPoint);
return tempSocket.Connected;
}
the above code is throwing SocketExceptions.
Any ideas are greatly appreciated.
Thanks, Josh
Remove this line: (it's for opening up a port for accepting clients)
tempSocket.Bind(ipEndPoint);
You want to act as a client by connecting to the server with:
tempSocket.Connect(ipEndPoint);
Are you really sure that you want to connet to port zero, i'm pretty sure this is not a valid choice. (standard HTTP = 80, HTTPS = 443)
var ipEndPoint = new IPEndPoint(IPAddress.Parse(exit.Address), 80);
I'm making a api service which connects to a SSL TCP server to retrieve data. I first made this api in C# and it works. Later I ported it to node.js to take the advantages of node.js. However I couldn't connect to the server.
Target :
Host : prodtw.lol.garenanow.com
Port : 2099
Code in C# which can connect to the server and works perfectly:
TcpClient client;
try
{
client = new TcpClient("prodtw.lol.garenanow.com", 2099);
Console.WriteLine("Connected to server.");
}
catch
{
Console.WriteLine("Error");
return;
}
SslStream sslStream = new SslStream(client.GetStream(), false, AcceptAllCertificates); //AcceptAllCertificate does nothing, just return true
var ar = sslStream.BeginAuthenticateAsClient("prodtw.lol.garenanow.com", null, null);
using (ar.AsyncWaitHandle)
{
if (ar.AsyncWaitHandle.WaitOne(-1))
sslStream.EndAuthenticateAsClient(ar);
}
// Connected, write something
byte[] handshakePacket = new byte[1537];
sslStream.Write(handshakePacket);
Code in node.js, which couldn't connect to the SSL TCP server :
var tls = require('tls');
console.log('Connecting');
var stream = tls.connect(2099, "prodtw.lol.garenanow.com", function() {
console.log('Successfully connected!'); //Never print this message.
});
After running the above node.js code, it never shows "Successfully connected". It only shows "Connecting" and stucks at tls.connect...
I am trying to get a rabbitMQ queue set up that sits on one pc, and recieves messagess from other computers giving it tasks. I have followed all the tutorials on the rabbit website but these only apply to local host. Can someone explain how I get this same code to communicate across 2 computers, not just from the same computer.
I have the following code:
Sender.cs
class Send
{
static void Main(string[] args)
{
Console.WriteLine("------------------");
Console.WriteLine("RabbitMQ Test");
Console.WriteLine("------------------");
var factory = new ConnectionFactory() { HostName = "localHost" };
try
{
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
channel.QueueDeclare("abc", false, false, false, null);
Console.WriteLine("Enter the messages you want to send (Type 'exit' to close program)...");
string message = null;
while (message != "exit")
{
message = Console.ReadLine();
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish("", "abc", null, body);
}
}
}
}
catch (Exception e)
{
string message = e.ToString();
}
}
Reciever.cs
class Recieve
{
static void Main(string[] args)
{
ConnectionFactory factory = new ConnectionFactory()
{
HostName = "localhost"
};
using (IConnection connection = factory.CreateConnection())
{
using (IModel channel = connection.CreateModel())
{
channel.QueueDeclare("abc", false, false, false, null);
QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume("abc", true, consumer);
Console.WriteLine(" [*] Waiting for messages." +
"To exit press CTRL+C");
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine("[Recieved]: {0}", message);
}
}
}
}
}
Is the idea to get these communicating across 2 computers to change the ConnectionFactory's hostname to the IP of the other computer or something to that extent? I have installed rabbit correctly on both computers, and this code runs correctly on each computer individually. I just need the communication to happen across the computers.
Any help would be greatly appreciated. I can't find any examples of this anywhere on the internet.
RabbitMQ is a centralized message queue. You would only install it on your server machine (or a cluster of server machines), and not on each publishing or subscribing client. Clients would then subscribe or publish to queues on the centralized machine.
In your development environment you should decide which of your two machines you want to act as the server. Then pass that hostname and password each client. Both clients should be working towards the same hostname.
var server = "http://127.0.0.1"; // An install of RabbitMQ reachable from both clients
var password = "guest";
var username = "guest";
var connectionFactory = new ConnectionFactory { HostName = server, Password = password , Username = username};
If you want to do message passing without installing something on a server you should take a look at ZeroMQ
You can check out shovel plugin - it is built to take messages messages from queue on one node of rabbit and publishes these messages on other one, while taking care of poor networking (WAN).
Check the official description
I was using Alchemy websockets for both my client and server but ran into a problem with corrupted/dropped messsages. So I'm trying out another server side implementation. I implemented the server using Fleck, and when I send messages using javascript, the server receives all the messages, solving my previous problem.
However, I need to be able to send messages to the websocket server from a C# client also. Since Fleck does not have a client side implementation in C#, I thought I'd stick with Alchemy. I left the client-side code unchanged so I thought it should just connect to the server as before, however, no messages are being received (though they are being sent according to the debugger).
Here is my server side implementation (Fleck):
private void OnStartWebSocketServer()
{
var server = new WebSocketServer("ws://localhost:11005");
server.Start(socket =>
{
socket.OnOpen = () => Console.WriteLine("Open!");
socket.OnClose = () => Console.WriteLine("Close!");
socket.OnMessage = message => OnReceive(message);
});
}
private static void OnReceive(String message)
{
UpdateUserLocation(message);
}
Here is my client side implementation (Alchemy):
class WSclient
{
WebSocketClient aClient;
public WSclient(String host, String port)
{
aClient = new WebSocketClient("ws://" + host + ":" + 11005 + "/chat")
{
OnReceive = OnReceive,
OnSend = OnSend,
OnConnect = OnConnected,
OnConnected = OnConnect,
OnDisconnect = OnDisconnect
};
aClient.Connect();
}
...
public void Send(String data)
{
aClient.Send(data);
}
I thought it might have something to do with the fact that the Alchemy client requires a channel at the end of the connection string '/chat'. However leaving it blank, or just the '/' gives an error.