I am writing this to find out why the code below is resulting in failed setup for supersocket server.
var appServer = new AppServer();
if (!appServer.Setup(8080)){
MessageBox.Show("Failed!");
}
I have added rule in firewall that allows port 8080 since my firewall is enabled by company IT. Don't know why the setup fails. Is there an explanation?
In testing this locally in a console application using the following (requires NuGet packages SuperSocket and SuperSocket.Engine;
namespace SupersocketTest
{
using System;
using SuperSocket.SocketBase;
class Program
{
static void Main(string[] args)
{
var server = new AppServer();
bool success = server.Setup(8080);
Console.WriteLine($"Server setup: {success}");
Console.ReadKey();
}
}
}
The operation completes successfully.
Looking at the code online, the underlying connection is still Socket based (as the name of the package implies). As such, it's subject to all the rules around how sockets work normally in .NET.
Things that can cause a Socket fail to be set up are (but not limited to)
The socket is in use
The socket has been closed
The OS has run out of available sockets (not likely but technically possible)
Without more detail on the exception you're getting I can only guess but I suspect that the socket is in use as 8080 is a common alternative to 80 that another application could be using.
Related
I'm using Unix Domain Socket for the first time,
I have created the following console application using .NET 5.0 to learn about Unix Domain Sockets.
I found the code here (https://medium.com/codex/unix-domain-sockets-in-net-6-basics-and-real-world-examples-8982898ab293)
My expectation is that similar to TCP/IP socket connection, i will be able to talk between the client and server but using Unix Domain sockets instead.
Following is the code:
class Program
{
static void Main(string[] args)
{
const string Hostname = "localhost";
const string UnixSocketPath = "/tmp/foo.sock";
using var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
var endpoint = new UnixDomainSocketEndPoint(UnixSocketPath);
socket.Connect(endpoint);
var requestBytes = System.Text.Encoding.UTF8.GetBytes($"GET / HTTP/1.0\r\nHost: {Hostname}\r\nAccept: */*\r\n\r\n");
socket.Send(requestBytes);
byte[] receivedBytes = new byte[1024];
socket.Receive(receivedBytes, 1024, SocketFlags.None);
Console.WriteLine(System.Text.Encoding.UTF8.GetString(receivedBytes));
}
}
I get the following error when i try to run my application:
"A socket operation encountered a dead network" at socket.Connect(endpoint) line.
I have the following questions:
Is it expected for the above console application to run in a windows system?
After reading couple of articles i understand that the "UnixSocketPath" is the file based path which is followed in a Unix machine. What does it refer to in case of a Windows machine? Or is it just a temporary file created in the output directory of the application.
I tried the following to resolve the error "A socket operation encountered a dead network" after reading up a bit on this:
Try to run the application in admin mode - does not work, same error
Switch to .net core 3.0 (even though i was not facing any compile time errors with .net 5.0)
does not work, same error.
Tried to change the "UnixSocketPath" to a local path (Eg: C:/Test/foo.sock ) - does not work, error : "No connection could be made because the target machine actively refused it. C:/Test/foo.sock"
Excuse me for these noob level questions, the entire socket level programming is new to me and i'm quite confused now .
Any suggestions are appreciated. Thanks
From your posted link:
To run the example on Windows-based systems, I can recommend WSL 2. Visual Studio and Visual Studio Code come with excellent remote integrations so you can run the code directly from the development environment.
WSL is "Windows subsystems for linux", i.e. a linux virtual machine that has some integrations with the windows host.
So you would need to run your program in this WSL environment, and have this configured correctly. See Debug .NET Apps in WSL with Visual Studio
However, if you just want your server and client to talk to each other I would consider if this really is the right approach. While unix domain sockets might have some performance advantages, you require both applications to be run on the same computer. I would just use some message based protocol and instead try to minimize the number and size of messages.
Expected Outcome
I'm attempting to make an ASP.NET Core 5.0 application using Kestrel, and I would like to auto port forward the server's port.
Package
I'm currently using the OpenNat.Core package. I have also tried the regular OpenNat and the same issue arises.
Issue
When port forwarding, the program says it has mapped everything correctly and the map even shows when listing all mapped ports on my router. Yet, when I attempt to view its status via CanYouSeeMe.org it returns a timed out error, and I am unable to access the server outside the network.
What I've Tried
I thought that the port mapping might have been opening after the server started, so I manually opened the port and then restarted the Kestrel server.
I made sure that my router supported UPnP
I also have a Synology NAS that I port forward from, and it works just fine.
I had a friend use ZenMap to check the port.
The port shows that it's filtered but not open (and no service was specified).
Code
using Open.Nat;
using System;
using System.Threading;
using System.Threading.Tasks;
...
public static async Task OpenPort(int port, string description)
{
try
{
NatDiscoverer discoverer = new NatDiscoverer();
CancellationTokenSource cts = new CancellationTokenSource(10000);
NatDevice device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts);
Mapping map = new(Protocol.Tcp, port, port, description);
await device.CreatePortMapAsync(map);
Console.WriteLine($"Created {map}");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
Nevermind my firewall was blocking the application. I was able to dynamically add a firewall rule to fix the issue.
I keep getting a SocketException: Address already in use when running my program multiple times.
Minimal example:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace test
{
class Program
{
static TcpListener listener;
static void Main(string[] args)
{
listener = new TcpListener(new IPEndPoint(IPAddress.Any, 3349));
listener.Start();
listener.BeginAcceptSocket(Accept, null);
Console.WriteLine("Started!");
// Simulate a random other client connecting, nc localhost 3349 does the same thing
var client = new TcpClient();
client.Connect("localhost", 3349);
Thread.Sleep(2000);
listener.Stop();
Console.WriteLine("Done!");
}
static void Accept(IAsyncResult result)
{
using(var socket = listener.EndAcceptSocket(result))
{
Console.WriteLine("Accepted socket");
Thread.Sleep(500);
socket.Shutdown(SocketShutdown.Both);
}
Console.WriteLine("Socket fully closed");
}
}
}
Run the program twice (dotnet run): the first time it will complete normally, but the second time it will fail saying "Address already in use".
Note that the missing dispose of client is not the problem here -- I can replicate the same error manually by using nc localhost 3349.
How can I clean up the listener so that I don't run into the error?
OS & .NET info:
dotnet --version
2.1.103
lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.4 LTS
Release: 16.04
Codename: xenial
This problem is not present on Windows. It also doesn't occur when using mono, so this seems to be specific to Microsoft's linux implementation.
This is actually intended behaviour. To fix the error, you should set the ReuseAddress socket option to true, if and only if the code is not running on Windows:
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
The difference between Windows and Linux (and presumably MacOS) is caused by the differences in the socket implementations:
On Windows, you can bind to an address and IP unless there's another connection active on the same address/IP combination.
On Linux, you can bind to an address unless there's any other connection on the same address/IP combination. This means that you cannot bind if there's still a connection in the TIME_WAIT or CLOSE_WAIT state.
As explained in this other question, SO_REUSEADDR can be used to relax these restrictions on Linux.
Mono has tried to emulate the behaviour of Windows by setting SO_REUSEADDR to true by default. The official .NET core runtime does not do this, and thus will cause the "Address already in use" error on Linux.
However this does not mean that it's safe to always set SO_REUSEADDR! On Windows, SO_REUSEADDR means something slightly different (source):
A socket with SO_REUSEADDR can always bind to exactly the same source
address and port as an already bound socket, even if the other socket
did not have this option set when it was bound. This behavior is
somewhat dangerous because it allows an application "to steal" the
connected port of another application.
Therefore, SO_REUSEADDR should only be set on non-Windows systems.
Please forgive me for the duplicate question. I know it has been asked here many times but none of the answers worked for me and none of the scenarios are quite the same as mine, and many of the questions have no answers at all.
I have been working on a project for university for a few weeks now but now have been tasked to change the full, working application to a client-server application (the details of the project are irrelevant). I plan on creating a console application that will be hidden and act as the server (will mainly handle SQL queries that will be executed on my database, then create objects based on the results of those queries, serialize them and send them across to the client). The client application is a Windows Forms application.
I am new to using sockets (only started with them 3 days ago but I believe I understand them pretty well - I am able to recreate a client-server chat application from knowledge (and logic) without referring to the code that I was given.)
I have done a lot of research to try fix it but now I have tried everything and I am hoping that someone can help me.
The problem I am having is that my client will not connect to the server. In my "practice" applications I have not had this issue and the client has always managed to connect.
I have tried:
Allowing the server (console) and client (forms) applications through the firewall
Disabling the firewall completely
Made sure the server is listening to the correct port number given on the client-side
I even copy-pasted the code (just the sockets part) from my project and created new server and client applications (which worked completely fine, exact same code, put in the exact same place as the original, worked fine in the new "test" applications but not in my project)
After trying these things with no success, I have realised that it is most likely not the firewall that is the issue and there cannot be a problem with the port number I used because the exact same code with the same port numbers worked in my "test" application.
I tried running netstat -anb as per this answer: https://stackoverflow.com/a/9695442/9886482
and I cannot see the port number anywhere.
A few of the other answers I saw on stackoverflow did not help me as most of them are using web services or actual server software which is not relevant or allowed in my case.
I have tried to give as much information as possible, and here is my code. Any help would be greatly appreciated.
Server Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HelperLibrary;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Farmulator_PRG221_Project
{
class Program
{
static void Main(string[] args)
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
serverSocket.Bind(new IPEndPoint(IPAddress.Loopback, port: 9000));
serverSocket.Listen(50);
Thread accepterThread = new Thread(new ParameterizedThreadStart(Accept));
accepterThread.Start(serverSocket);
}
static void Accept(object obj)
{
Socket serverSocket = (Socket)obj;
while (true)
{
Socket clientSocket = serverSocket.Accept();
Console.WriteLine("New client connected!");
}
}
Client code:
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
clientSocket.Connect(new IPEndPoint(IPAddress.Loopback, port: 9000));
I'm now implementing my academic project software using named pipe technologies to connect heterogeneous systems over the network. I used .net framework 4 and C# language. The problem is that the client program will not able to continue if the server is not ready or unavailable. The client named pipe continuously try to connect to the server named pipe until available connectivity.
I want the client program to be able to continue other functions if the server connection is not available within 3 seconds (may be any duration). Like this scenario: When the client program is started, it will try to connect to server. If the server is not available, the client will stop trying to connect to server and run offline by itself.
some code snippet of my problem...
pipeClient.Connect(); <-- this is the problem point,
frmUserprofile.show(); <-- until the connection is available, the program will not execute this line
the solution that I would like to get...
pipeClient.Connect()
if (3 seconds is over && server connection is unavailable) <-- this is what I need
{ pipeClient stops try to connect; }
frmUserprofile.show();
can someone help me to give some practical solution to me...
by the ways, I hope if u can solve this problem with C# language, please give answers with C# but not necessarily
thanks in advance...
If you are using NamedPipeClientStream class, there is Connect(int) method overload, which accepts timeout value:
bool isConnected = false;
try
{
pipeClient.Connect(3000);
isConnected = true;
}
catch(TimeoutException)
{
// failed to connect
}
If you use NamedPipeClientStream for your task there is Connect(Int32) method that takes amount of timeout
http://msdn.microsoft.com/en-us/library/bb355337.aspx
Use the NamedPipeClientStream. It has a connect time out.
See NamedPipeClientStream.Connect