SocketException when attempting to connect with TcpClient - c#

When I try to create a new TcpClient I am getting a SocketException, here is my code:
public void TcpOpenConnection()
{
// The next line is where the exception is occurring.
tcpClient = new TcpClient(ipAddress, port);
connected = true;
}
I have checked to make sure the port is open with netstat -a in cmd, and I even made another function to check if the port is open:
public static bool PortCheck(int port)
{
bool portOpen = false;
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] tcpConnInfo = ipGlobalProperties.GetActiveTcpConnections();
foreach (var tcpConn in tcpConnInfo)
{
if (tcpConn.LocalEndPoint.Port == port)
{
portOpen = true;
break;
}
}
return portOpen;
}
which returns true. The exception that I am getting is a SocketException and it is saying the machine I am trying to connect to is actively refusing the connection. What could be the issue here? I have also tried other ports, with no luck.
If you need more info please ask, and I will gladly supply more.

The exception that I am getting is a SocketException and it is saying the machine I am trying to connect to is actively refusing the connection.
This is likely an indication that the target host isn't listening on the port which could be caused by a number of reasons:
The router of the server's network is not correctly port-forwarded
The router's firewall / server's firewall is blocking the connections
The server and the client are not using the same port
The server is misconfigured
The list goes on... but essentially, this error means that the server isn't allowing the connection.

If the port is open and you try to connect to. You get SocketException because there is nothing for get the client connection.
So you need to host a Tcplistner on this port.
static void StartServer()
{
int port = 150;
TcpListener listner = new TcpListener(IPAddress.Any, port);
listner.Start();
// This line waits the client connection.
TcpClient remote_client = listner.AcceptTcpClient();
// do something with remote_client.
}
And you can connect to.
static void StartClient()
{
int port = 150;
IPAddress ip = IPAddress.Parse("127.0.0.1");
TcpClient client = new TcpClient();
client.Connect(ip, port);
// Do something with client.
}

Related

Public TCP server with C# hosted on my computer

I'm trying to run a game TCP/UDP server on my computer. It's working fine within the local network, but when I'm trying to run the server with my public IP, it just doesn't work. I've tried to disable the firewall in my router, set port forwarding for port 17000 and added a firewall rule to my computer. I've also bound IP to my computer.
I've checked client calls with Wireshark and I found out that the client (Unity game) is sending data to my IP, but it's giving TCP Retransmission error for every TCP packet that it is trying to send.
There is some of the code from server and client.
Server IP is set to 192.168.0.*:17000
And the client is connecting to my IP with port 17000
SERVER:
public static void Start(byte _maxPlayers)
{
MaxPlayers = _maxPlayers;
Port = 17000;
Console.WriteLine("Starting server..");
InitializeServerData();
tcpListener = new TcpListener(GetLocalIPAddress(), Port);
tcpListener.Start();
tcpListener.BeginAcceptTcpClient(new AsyncCallback(TCPConnectCallback), null);
udpListener = new UdpClient(Port, GetLocalIPAddress().AddressFamily);
udpListener.BeginReceive(UDPReceiveCallback, null);
Console.WriteLine($"Server started on {tcpListener.LocalEndpoint}.");
}
CLIENT:
public void Connect()
{
socket = new TcpClient
{
ReceiveBufferSize = dataBufferSize,
SendBufferSize = dataBufferSize
};
receiveBuffer = new byte[dataBufferSize];
socket.BeginConnect(instance.ip, instance.port, ConnectCallback, socket);
}
private void ConnectCallback(IAsyncResult _result)
{
socket.EndConnect(_result);
if (!socket.Connected)
return;
stream = socket.GetStream();
receivedData = new Packet();
stream.BeginRead(receiveBuffer, 0, dataBufferSize, ReceiveCallback, null);
}
So I've found out, that I have two-router set up, and because I was forwarding port 17000 just on one router, it didn't work.

How do I connect to a Windows Universal App StreamSocket from a Console Application?

I am listening for connections through a Windows Universal App and would like to connect to that App through a Windows Console Application. I have done some basic code which I think should connect but I get a timeout error from the console application.
{"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 192.168.0.5:1771"}
The windows universal app never even goes into the connection received function.
The Server (UWP):
public async void SetupServer()
{
try
{
//Create a StreamSocketListener to start listening for TCP connections.
Windows.Networking.Sockets.StreamSocketListener socketListener = new Windows.Networking.Sockets.StreamSocketListener();
//Hook up an event handler to call when connections are received.
socketListener.ConnectionReceived += SocketListener_ConnectionReceived;
//Get Our IP Address that we will host on.
IReadOnlyList<HostName> hosts = NetworkInformation.GetHostNames();
HostName myName = hosts[3];
//Assign our IP Address
ipTextBlock.Text = myName.DisplayName+":1771";
ipTextBlock.Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(255,0,255,0));
//Start listening for incoming TCP connections on the specified port. You can specify any port that' s not currently in use.
await socketListener.BindEndpointAsync(myName, "1771");
}
catch (Exception e)
{
//Handle exception.
}
}
The Client (Console Application):
static void Main(string[] args)
{
try
{
byte[] data = new byte[1024];
int sent;
string ip = "192.168.0.5";
int port = 1771;
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), port);
TcpClient client = new TcpClient();
client.Connect(ipep); //**************Stalls HERE************
using (NetworkStream ns = client.GetStream())
{
using (StreamReader sr = new StreamReader(ns))
{
using (StreamWriter sw = new StreamWriter(ns))
{
sw.WriteLine("Hello!");
sw.Flush();
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Response: " + sr.ReadLine());
}
}
}
}
catch (Exception e)
{
}
}
I have tested your code on my side and it can work well. So there is nothing wrong with your code. But I can reproduce your issue by running the server and client on the same device, the client will throw the same exception as you showed above. So please ensure you're connecting from another machine. We cannot connect to a uwp app StreamSocketListener from another app or process running on the same machine,this is not allowed. Not even with a loopback exemption.
Please also ensure the Internet(Client&Server) capability is enabled. And on the client you can ping the server 192.168.0.5 successfully.

beginAccept() asynchronous server issue in C#

I'm struggling with some piece of simple code. However, I can't get it done. I have this server, which must accept connections from multiple clients (asynchronously, obviously). So, I have:
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 8082);
TcpListener tcpListener = new TcpListener(IPAddress.Any, 8082);
server = tcpListener.Server;
server.Bind(ipEndPoint);
server.Listen(4);
server.BeginAccept(new AsyncCallback(beginConnection), server);
And,
static void beginConnection(IAsyncResult iar)
{
Console.WriteLine("Client connected");
Socket s = (Socket)iar.AsyncState;
server = s.EndAccept(iar);
server.Listen(4);
server.BeginAccept(beginConnection, s);
}
Then, when I try to connect myself, the first client works OK. It just sends a message to this server, and the server sends it back to the client. The server functions as an echo. But when I try to connect another clients it doesn't work. I have also put the Console.WriteLine("Client connected"), but the server doesn't write anything.
How can I fix this problem?
I think I'm not passing the right parameter to the first BeginAccept method. Instead of server socket, I should be passing the tcpListener.
Then I would have:
static void beginConnection(IAsyncResult iar)
{
Console.WriteLine("Client connected");
TcpListener tcpListener = (TcpListener)iar.AsyncState;
Socket s = tcpListener.Server.EndAccept(iar);
tcpListener.Server = s; // But I would have this error
server.Listen(2);
server.BeginAccept(beginConnection, s);
}
But I would have the error that I marked it up. In the first version nothing is modified, so I think this it's the issue in the first version of the code.
First, you do not need the Server property of the TcpListener. You should simply call Start(), even without Bind.
Second, EndAccept() is also should be called at TcpListener and return a TcpClient instance which you must use for sending and receiving data.
A simple example of what I just said might be presented as:
{
TcpListener listener = new TcpListener(IPAddress.Any, 8082);
listener.Start();
AcceptClient();
}
void AcceptClient()
{
listener.BeginAccept(ClientConnected, null);
}
void ClientConnected(IAsyncResult ar)
{
TcpClient client = listener.EndAccept();
AcceptClient();
// Now you can send or receive data using the client variable.
}

Is there any way to improve TCP connection time?

I wrote a TCP server to use the BeginAccept/EndAccept pattern. With this, I coded up a simple UnitTest using a TcpClient, and measured each portion. All tests are localhost, so I am surprised to see that TCP connection is consistently taking 1 second. I have set the Socket.NoDelay = true although I believe this only affects Send/Receive. I am not receiving the first packet of data. Any help or ideas on speed this up are appreciated.
Note: I can not change the client side to keep the connection open, and I need to be able to handle a lot of requests per second if possible.
Server Side:
public void Start()
{
System.Net.IPHostEntry localhost = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
System.Net.IPEndPoint endpoint;
int port = Properties.Settings.Default.ListenPort;
//
// Setup the connection to listen on the first IP, and specified port
//
endpoint = new IPEndPoint(IPAddress.Any, port);
listenSocket = new Socket(endpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(endpoint);
listenSocket.NoDelay = true; // do not wait 200 milliseconds for new data to be buffered on the connection
listenSocket.Listen(int.MaxValue);
Console.WriteLine("Listening on {0}:{1}", localhost.AddressList[0], port);
//
// Post the accept. The accept method will continuously post a new accept as soon as a connection is made
//
while (true)
{
accepted.Reset();
Connection connection = connections.Pop();
listenSocket.BeginAccept(AcceptCallback, connection);
accepted.WaitOne();
}
}
private static void AcceptCallback(IAsyncResult ar)
{
accepted.Set();
Connection connection = ar.AsyncState as Connection;
Socket remoteSocket = null;
try
{
remoteSocket = listenSocket.EndAccept(ar);
remoteSocket.NoDelay = true;
connection.RemoteSocket = remoteSocket;
//
// Start the Receive cycle
//
Receive(connection);
}
catch (SocketException)
{
Disconnect(connection);
}
}
Simple Test Client:
[TestMethod()]
public void ClientTest()
{
TestContext.BeginTimer("Connection");
TcpClient client = new TcpClient("localhost", 10300);
NetworkStream stream = client.GetStream();
TestContext.EndTimer("Connection");
...
Using a LoadTest I loaded 25 users, and the Transaction "Connection" always takes above 1 second.
Not sure why, but simply changing this:
TestContext.BeginTimer("Connection");
TcpClient client = new TcpClient("localhost", 10300);
TestContext.EndTimer("Connection");
To this:
TestContext.BeginTimer("Connection");
TcpClient client = new TcpClient();
client.Connect("localhost", 10300);
TestContext.EndTimer("Connection");
Drops the time from 1 second to .13 seconds. Will have to investigate as to why, but hopefully this will help somebody out in the future.
When you attempt to connect using the TcpClient constructor on a host that resolves to both Ipv6 and Ipv4 addresses, the connection using Ipv6 is attempted first. If it fails then it attempts to connect using the Ipv6 address. This is the cause of the 1 second delay. Here is the MSDN link:

Unable to connect from remote machine

I have some kind of problem and I can't check this at home if its working or not.
Here is the code
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Net.Security;
class Program
{
private static IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
private static int port = 6000;
private static string data = null;
static void Main(string[] args)
{
Thread thread = new Thread(new ThreadStart(receiveThread));
thread.Start();
Console.ReadKey();
}
public static void receiveThread()
{
while (true)
{
TcpListener tcpListener = new TcpListener(ipAddress, port);
tcpListener.Start();
Console.WriteLine("Waiting for connection...");
TcpClient tcpClient = tcpListener.AcceptTcpClient();
Console.WriteLine("Connected with {0}", tcpClient.Client.RemoteEndPoint);
while (!(tcpClient.Client.Poll(20, SelectMode.SelectRead)))
{
NetworkStream networkStream = tcpClient.GetStream();
StreamReader streamReader = new StreamReader(networkStream);
data = streamReader.ReadLine();
if(data != null)
Console.WriteLine("Received message: {0}", data);
}
Console.WriteLine("Dissconnected...\n");
tcpListener.Stop();
}
}
}
I have a simple program as well to connect to this and then send a string with data. It works fine on localhost but there is a problem when I'm trying to connect with a different coputer.
I even turned off the firewall on my PC and router, as I did on my friend's laptop. Every time I have tried to connect, his computer refused connection. Maybe I'm doing something wrong?
Of course, ipAddress is a local address now since it's only working with that at the moment. Any suggestions what to do?
You need to set it to accept connections from any IP, there is an IPAddress overload function for this:
System.Net.IPAddress.Any
use it instead of 127.0.0.1 and it will fix your problem.
You're listening on 127.0.0.1 which is the loopback address which is a special address that means 'this computer'. This means that you will only accept connections that are made on the same machine as the server is running on.
You need to listen on one (or more) of the server's real ip addresses.
Your problem is that the setting an IP address explicitly when you initialize the TcpListener will only allow it to accept connections from that address. Therefore, putting in the local address of 127.0.0.1 will only accept connections originating from your PC.
The implementation you want to use is as follows:
TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
This will allows connections from any IP address to connect to your program on the specified port.
I think it is your computer (the server) that refuses to connect because 127.0.0.1 is local(-only).
Try this simple overload:
TcpListener tcpListener = new TcpListener(port);

Categories