Connection specific AppendShutdownHandler - c#

I'm using NetworkComms.Net and I'm currently trying to create a sort of forwarder which listens on a port (calling it GATEWAY), which receive a certain packet (from CLIENT) which will tell him where to redirect next pacekts coming from the same client.
Example:
CLIENT tell GATEWAY that he needs to get to SERVER:serverport
GATEWAY creates a connection to SERVER:serverport
CLIENT sends packets to GATEWAY which sends them to SERVER
SERVER sends back a response, which goes through the GATEWAY to the CLIENT.
I had it working with Net.Sockets and I’m now changing to NetworkComms.
The problem I’m facing is that when a connection from Gateway (client) to Server (listening server) is closed, the Gateway trigger the global callbacks for connection/disconnection:
NetworkComms.AppendGlobalConnectionCloseHandler(ClientDisconnected);
NetworkComms.AppendGlobalConnectionEstablishHandler(ClientConnected);
Those callbacks are supposed to be only called when a client connect or disconnect on the Gateway
This is the code i’m currently using to start the listener.
NetworkComms.DefaultSendReceiveOptions = new SendReceiveOptions<ProtobufSerializer, , LZMACompressor>();
NetworkComms.DefaultSendReceiveOptions.IncludePacketConstructionTime = NetworkComms.DefaultSendReceiveOptions.ReceiveHandlePriority = QueueItemPriority.AboveNormal;
NetworkComms.AppendGlobalConnectionCloseHandler(SessionClosed);
NetworkComms.AppendGlobalConnectionEstablishHandler(NewSessionConnected);
NetworkComms.AppendGlobalIncomingPacketHandler<string>("ECHO", SocketCommands.HandleIncomingECHOPacket);
Connection.StartListening(ConnectionType.TCP, new IPEndPoint(IPAddress.Any, 10000));
I suppose this is like a “global” way of starting It?
How do I start one then add those Connected/Disconnected handlers to just the listener?
Thanks

Related

Why does my basic tcp chat application only work when connections are ended via ECONNRESET in nodejs?

I have a weird scenario and I'm not sure how to solve it.
I have a simple tcp chat server in nodejs and my clients are currently in native C#, and eventually will move to Unity. I have my own networking library which creates the TCP connection and handles messages etc, and works fine in some cases until it comes to disconnecting.
The server is running on an EC2 instance and I am loading two windows on my PC to test the multiple connections. When I close the window, I receive this error in the nodejs server console
Error: read ECONNRESET
at exports._errnoException (util.js:870:11)
at TCP.onread (net.js:544:26)
Which is fine, because this is the scenario where it works. I'm guessing this just means that the connection was abruptly closed (closing the window).
However problems arise when I instruct the socket to be shutdown.
I am porting my client to Unity and when closing the client, it does not produce this ECONNRESET error and the connection never closes abruptly (like I'd expect it to), so in this case I have to manually close the connection on the client which results in a different error.
Error: This socket has been ended by the other party
at Socket.writeAfterFIN [as write] (net.js:268:12)
at /opt/chat/chat.js:32:10
at Array.forEach (native)
at broadcast (/opt/chat/chat.js:31:10)
at Socket.<anonymous> (/opt/chat/chat.js:26:2)
at emitNone (events.js:72:20)
at Socket.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:905:12)
at nextTickCallbackWith2Args (node.js:441:9)
at process._tickCallback (node.js:355:17)
When I receive this error on the server, the other connected clients can continue messaging the server, however they cannot receive messages from it.
My nodejs server was pulled from github here:
https://gist.github.com/creationix/707146
// Load the TCP Library
net = require('net');
// Keep track of the chat clients
var clients = [];
// Start a TCP Server
net.createServer(function (socket) {
// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort
// Put this new client in the list
clients.push(socket);
// Send a nice welcome message and announce
socket.write("Welcome " + socket.name + "\n");
broadcast(socket.name + " joined the chat\n", socket);
// Handle incoming messages from clients.
socket.on('data', function (data) {
broadcast(socket.name + "> " + data, socket);
});
// Remove the client from the list when it leaves
socket.on('end', function () {
clients.splice(clients.indexOf(socket), 1);
broadcast(socket.name + " left the chat.\n");
});
// Send a message to all clients
function broadcast(message, sender) {
clients.forEach(function (client) {
// Don't want to send it to sender
if (client === sender) return;
client.write(message);
});
// Log it to the server output too
process.stdout.write(message)
}
}).listen(5000);
// Put a friendly message on the terminal of the server.
console.log("Chat server running at port 5000\n");
Scenario
Let's assume we have CLIENT A on the left and CLIENT B on the right
On initial connection, they can both chat fine.
CLIENT B wishes to disconnect, and the code forces the disconnect by terminating the socket. The nodejs server receives the error "This socket has been ended by the other party" and broadcasts that this player has disconnected to CLIENT A
CLIENT A wishes to continue communicating, regardless that no one is connected. CLIENT A continues typing and sending messages, however the messages are not being received once CLIENT B has disconnected. However, the messages are indeed being sent to the server.
CLIENT A is NOT receiving his own messages.
CLIENT B wishes to reconnect to continue chatting and does so.
CLIENT A sends message 'hello'
CLIENT B sends message 'hello'
CLIENT B is seeing both messages, and experiencing a normal chat, however CLIENT A is not seeing any of the messages and is stuck on a blocking call trying to read data.
This is ONLY when I force the socket closed, and it works perfectly fine when I receive the ECONNRESET error. How can I replicate this error, or fix my issue?
EDIT
I have managed to reproduce the ECONNRESET error and now it works, but it still doesn't explain why it doesn't work with other errors.
The methods Close and GetStream().Close in C# TcpClient are not sufficient it seems to close a connection properly. Instead I had to access the socket directly and close that.
Closing the socket directly works in a native C# application but not in Unity.
To replicate this error in Unity I have to use
Shutdown(SocketShutdown.Receive);

UDP UWP server + Mono2x client

I have a really weird issue with communication between server and client using UDP protocol. Client is written in Mono2x (I use Unity 3D as my client) and creates UdpClient class instance:
_udpClient = new UdpClient(9050);
_serverEP = new IPEndPoint(IPAddress.Parse(_serverIp), _serverPort);
My server is UWP application I want to run on Raspberry Pi that is using DatagramSocket:
_udpServer = new DatagramSocket();
_udpServer.MessageReceived += ClientCheck;
await _udpServer.BindServiceNameAsync(port.ToString());
I send data from client to server but with no luck. I checked with TCPView that data is send from my client application but never reaches the server. And now is the weird part. When I receive message from server first (I hardcode port to client), my client is able to send data with a success.
I am using same IPEndPoint to send data from client without any changes after receiving packet from server, it just starts working. Honestly, I have no idea what I could do wrong, so I will be thankful for any advice.
And now is the weird part. When I receive message from server first (I hardcode port to client), my client is able to send data with a success
This is a known issue which is filed based on this related question: https://stackoverflow.com/a/39767527/5254458
It includes the issue's description and temporary workaround.
The corresponding is team is investigating it and I can not guarantee that when the fix will be delivered.

Tcp Server Only Allowing 1 Client

Server.cs - https://hastebin.com/enajinewij.cs
Client.cs - https://hastebin.com/iriperubur.cs
I have tried both running the Client on another PC and running it on one PC, but both result in the Client not being able to receive or send any messages.
I CANT portforward. I am using Hamachi for the IP Address. Both client and server are connected to my Network and are using the Hamachi IP Address. I am using PDA Net to connect to the internet from my PC.
The Server does not see them connect at all. Nor does the Server get any messages from them. Currently only the Server can send messages, and only it can get them.
I am not getting ANY errors at all, so I am not sure how I should handle solving this issue as it's my first time working with networking.
At first you create a TcpListener and you call StartLis() that does BeginAcceptTcpClient. However in AcceptTCPClient you create a new TcpListener and BeginAcceptTcpClient is not called.
You don't have to create a new listener for each connection, but you do have to call BeginAcceptTcpclient again:
private void AcceptTCPClient(IAsyncResult ar)
{
TcpListener Lis = (TcpListener)ar.AsyncState;
Clients.Add(new ServerClient(Lis.EndAcceptTcpClient(ar)));
StartLis(); // this will call BeginAcceptTcpClient again
}

Handler for pong message in WampSharp client

I have a WampSharp client which successfully pings my Wamp WS server created in python every 1 minute.
I am sending a pong message from the server to the client on the receipt of the ping.
I would like to know whether there is any handler which will handle the receipt of the pong message in WampSharp client so that I could perform certain tasks at client side?
And if there isn't any separate handler for the pong message then is there any handler to handle the data received from the server like in traditional WebSocket client which is as follows?
webSocket.MessageReceived += new EventHandler<MessageReceivedEventArgs>(webSocket_MessageReceived);
Thanks in advance.
I just uploaded to NuGet a version of WampSharp that allows you to specify the underlying WebSocket you want to use for a WampChannel.
Usage:
DefaultWampChannelFactory factory = new DefaultWampChannelFactory();
WebSocket socket = new WebSocket("ws://localhost:9090/ws", "wamp");
IWampChannel<JToken> channel = factory.CreateChannel(socket);
socket.DataReceived += OnDataReceived;
await channel.OpenAsync();
As you see, you can also subscribe to underlying WebSocket's events. I don't really like this, since this removes WampSharp's WebSocket encapsulation, but if you know what you're doing, I won't stop you.

Spoof IP address for HTTP web request?

I have a web service on a server in my company that we have restricted access to from all but one other server on our network.
I do however need to make calls to this from another machine. Is there a way I can spoof the other servers IP address in order to send an http request to the web service? I only need to send it info I don't need any returned data. It's for logging hits from another server on our main server.
I am using this
IPEndPoint endpointAddress = new IPEndPoint(IPAddress.Parse(ipAddress), 80);
using (Socket socket = new Socket(endpointAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
socket.SendTimeout = 500;
socket.Connect(endpointAddress);
socket.Send(byteGetString, byteGetString.Length, 0);
}
but get an exception
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
23.202.147.163:80
In general, it is not possible to establish a TCP connection with a server without being able to receive and process some reply packets from that server. HTTP is built upon TCP, and TCP starts communications with a "3-way handshake" that lets the client and server communicate.
The start of an HTTP request is not a single packet.
You could use a proxy to bounce your requests from an IP address that has access.

Categories