I ran an application on my machine and it ran fine; I then run the apoplication on another machine but I'm getting a socket timeout isse connecting to the box even though Pinging works fine. Below is my socket connection Logic:
private bool openConnection(out IPEndPoint connection_Point)
{
bool connected = false;
connection_Point = new IPEndPoint(m_address, m_port);
m_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
try
{
m_sock.Connect(connection_Point);
connected = true;
}//end of try logic
catch (SocketException err)
{
connected = false;
connection_Point = null;
MessageBox.Show("Socket Exception thrown: " + err);
}
return connected;
}
ping will only tell if the IP address responds to pings. To confirm that a TCP socket can be opened, try telnet on the listening port from the new machine. If telnet doesn't connect, the likely culprits are firewall and/or IPSec.
Firewall? Sounds like firewall to me...
Related
I cannot find any example or a tutorial on how to send data from C# to python.
in my application, C# is supposed to keep reading data from a hardware and send it to python to be processed. i have tried to create a basic server on python and a basic client on C# and i was never able to establish connection between the client and the server with the following output from C# No connection could be made because the target machine actively refused it. i tested my python server on a python client and i was able to establish connection just fine.
how do i send data from C# to python correctly using sockets? is there any available tutorial on example i can follow? is there something wrong with my code? here it is:
Python Server code:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established!")
clientsocket.send(bytes("Welcome to the server!", "utf-8"))
clientsocket.close()
C# Client Code:
static void ExecuteClient()
{
try
{
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 1234);
Socket sender = new Socket(ipAddr.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
try
{
sender.Connect(localEndPoint);
Console.WriteLine("Socket connected to -> {0} ",
sender.RemoteEndPoint.ToString());
byte[] messageReceived = new byte[1024];
int byteRecv = sender.Receive(messageReceived);
Console.WriteLine("Message from Server -> {0}",
Encoding.ASCII.GetString(messageReceived, 0, byteRecv));
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
// Manage of Socket's Exceptions
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
I know this question is old, but incase some else stumbles here in their internet searching.
I just started down the road of learning Python and I'm working on a similar situation with my Raspberry Pi (SERVER) and Windows PC (CLIENT).
The problem is you're making a call to get the hostname on each machine. This is will obviously be different. Your client needs to connect to the address of the server. Your client code is trying to connect to the machine it's running and that connection is being refused. The server is never contacted.
I made the following changes and was able to establish a connection.
Python Server code:
s.bind(("", 1234))
C# Client Code:
//IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
//IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("[SERVER IP]"), 1234);
Server Console Response:
Connection from ('[CLIENT IP]', 52074) has been established!
Client Console Response:
Socket connected to -> [::ffff:[SERVER IP]]:1234
Message from Server -> Welcome to the server!
Punching the UDP network works and works. However, when it comes to TCP, it's possible that I'm writing something wrong but I'm not a beginner programmer, or maybe I don't understand something.
Of course, I'll shorten a bit, we assume that we already have something as trivial as connection to an external server :)
Packet synchronization between threads as well as their creation, queuing, serialization, sending raw bytes and much more I skip because it is about the element of creating TCP sockets and not what works.
We will use the TcpListener class for the server.
public void InitializeServer(IPAddress address, int port)
{
try
{
// 127.0.0.1 accept only local connections, 0.0.0.0 is open for whole internet connections
listener = new TcpListener(address, port);
socket = listener.Server;
// Enable NAT Translation
listener.AllowNatTraversal(true);
// Start listening for example 10 client requests.
listener.Start(listenQueue);
Debug.Log($"[L{socket.LocalEndPoint}]Server start... ", EDebugLvl.Log);
OnServerInitialize(true);
// Enter the listening loop.
StartListener();
}
catch (SocketException e)
{
Debug.LogError($"SocketException: {e}", EDebugLvl.Error);
OnServerInitialize(false);
}
}
We start listening
private void StartListener()
{
Debug.Log("\nWaiting for a connection... ");
listener.BeginAcceptTcpClient(AcceptCallback, listener);
}
When the server receives the connection, we create a new socket
private void AcceptCallback(IAsyncResult ar)
{
TcpListener server = (TcpListener)ar.AsyncState;
TcpClient newClient = null;
try
{
newClient = server.EndAcceptTcpClient(ar);
}
catch (Exception e)
{
Debug.LogError(e.ToString());
}
if (newClient != null && newClient.Connected)
{
//...
client.StartRead();
}
//Loop
StartListener();
}
We create a new socket at the client and try to establish a connection
public void Connect(IPEndPoint remote, IPEndPoint bind = null, bool reuseAddress = false)
{
if (bind == null)
{
client = new TcpClient();
}
else
{
client = new TcpClient(bind);
}
socket = client.Client;
if (reuseAddress)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, reuseAddress);
//It throws me a error SocketOption so im comment this.
//socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseUnicastPort, reuseAddress);
}
client.BeginConnect(remote.Address, remote.Port, ConnectCallback, null);
}
The connection works without any problems and data transfer.
Unfortunately, here as we know, we must start a new socket listening on the same address and port that was created when connecting to the server. I do this for every client.
public void StartHost(Client server)
{
if (server != null && server.socket.Connected)
{
IPEndPoint localHost = (IPEndPoint)server.socket.LocalEndPoint;
InitializeHost(localHost.Address, localHost.Port);
}
}
public void InitializeHost(IPAddress address, int port, bool reuse = false)
{
try
{
listener = new TcpListener(address, port);
socket = listener.Server;
if (reuse)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseUnicastPort, true);
}
// Enable NAT Translation
listener.AllowNatTraversal(true);
// Start listening for example 10 client requests.
listener.Start(listenQueue);
Debug.Log($"\n[L{socket.LocalEndPoint}]Host start... ", EDebugLvl.Log);
OnServerInitialize(true);
// Enter the listening loop.
StartListener();
}
catch (SocketException e)
{
Debug.LogError($"SocketException: {e}", EDebugLvl.Error);
OnServerInitialize(false);
}
}
private void StartListener()
{
Debug.Log("\nWaiting for a connection... ");
listener.BeginAcceptTcpClient(AcceptCallback, listener);
}
private void AcceptCallback(IAsyncResult ar)
{
TcpListener server = (TcpListener)ar.AsyncState;
TcpClient newClient = null;
try
{
newClient = server.EndAcceptTcpClient(ar);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
if (newClient != null && newClient.Connected)
{
//...
client.StartRead();
}
//Loop
StartListener();
}
So, as they write everywhere ... client "B" sends a packet to the server that wants to establish a connection, the server sends information to the client "A" about the client "B" and vice versa
Then they both try to connect with the new socket? No problem...
public void Connect(IPEndPoint remote, IPEndPoint bind = null, bool reuseAddress = false)
{
if (bind == null)
{
client = new TcpClient();
}
else
{
client = new TcpClient(bind);
}
socket = client.Client;
if (reuseAddress)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, reuseAddress);
//socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseUnicastPort, reuseAddress);
}
client.BeginConnect(remote.Address, remote.Port, ConnectCallback, null);
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
client.EndConnect(ar);
}
catch (Exception e)
{
Debug.LogError(e.ToString(), EDebugLvl.ConnectionError);
}
if (client.Connected)
{
Debug.Log($"[P{socket.RemoteEndPoint}, L{socket.LocalEndPoint}]Connected", EDebugLvl.ConnectionLog);
stream = new NetworkStream(socket, FileAccess.ReadWrite, true);
StartRead();
}
ConnectedComplete(this, socket.Connected);
}
No matter how many times I try, the connection is rejected ... the addresses match everywhere and yet it does not work, so I have nothing to write about in this case, especially since UDP works for me.
What I wrote only works on the same NAT network. Unfortunately, I noticed that on the same NAT created two connections. One is the result of trying to connect the new socket A to B and the other is the result of receiving a new connection from B to A, so each client has one unnecessary socket connected by a local address. So all NAT TCP / IP Punch NAT doesn't work for me. I can actually use UDP but I really need TCP. I have been sitting on it for several months in my free time but nowhere can I find an example from the code and not the theory of which there is a lot.
I accumulated a lot of knowledge for 8 years and from 2 I write applications using sockets and finally I need to punch the net.
Why won't I use the ready solution? I need my own which is fully open using only UDP and TCP because some target devices only support these protocols. I also used the Socket class but this one did not give me a working copy.
Maybe someone will be able to help me for which I would be very grateful and certainly the post will also help others understand this.
Regards
Octavian
NAT hole punching only works with UDP, and even that is a hack.
NAT firewall implementations will start tracking a TCP stream when they see the initial SYN packet leaving the network. To capture incoming TCP streams you need to create an incoming rule on the router, there's no way around this. If the router supports UPnP, you can ask it to create that rule for you dynamically.
Since UDP doesn't have a SYN packet equivalent, routers will start tracking the stream on any outgoing packet. This is why NAT hole punching works. If both end points are behind NAT and just assume that the link will work. Both can just start sending UDP packets to each other. The routers will add the connection state, and map the incoming packets to each endpoint.
My friend runs a simple C# Console Application that starts a TcpListener on Port 8484. This is how it's being done:
public static void Listen()
{
Listener = new TcpListener(IPAddress.Any, 8484);
Listener.Start();
Listener.BeginAcceptSocket(new AsyncCallback(EndAccept), null);
}
public static void EndAccept(IAsyncResult IAR)
{
Console.WriteLine("Connection accepted on Port 8484.");
Socket socket = Listener.EndAcceptSocket(IAR);
Instance = new Client(socket);
Listener.Stop();
Listener = null;
}
I connect to him using:
public void Connect()
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
_socket.Connect(IP, Port);
Debug.WriteLine("Connected with server!");
}
catch (Exception ex)
{
Debug.WriteLine(TypeName + " [ERROR] Could not connect to server # {0}:{1}: {2}", IP, Port, ex.Message);
}
}
However, for some reason - he can't accept the connection, it says it doesn't respond. Port 8484 is 100% opened at his computer.
Why does this happen?
Use telnet to verify connectivity to the remote server. E.g. run the command "telnet ip_address port". If it successfully connects then you can reach the server. If telnet cannot connect then you cannot reach the server, likely due to a firewall issue.
Try disabling the firewall.1
1 - Helped user in chat to test for firewall problems, and it has not open. That has the problem
I am connecting to a remote server in C# via a socket and sending data across, upon disconnect I try to re-establish the connection by creating a new socket and reinitialising it.
This works for me when I test by pulling out the ethernet cable and reconnecting it a few mins later, but occasionally (every few hours maybe) I get the one of two exceptions while connected and cannot reconnect...
System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine
.......
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
If I restart the application everything works fine once again, so im curious as to why creating a new socket doesnt work. Am I missing an initialisation somewhere perhaps? Any ideas? I use the same method for connection each time:
public static bool OpenConnection(string siteName)
{
bool success;
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(serverIp), Convert.ToInt16(serverRemotePort));
try
{
client = null;
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Console.WriteLine("Try to connect to the server ..." + ip.Address.ToString());
client.Connect(ip);
Console.WriteLine("Connection established");
//Send the nameSite first
string nameSite = EncryptString(siteName, pwd, initVector) + "*";
byte[] dataSite = new byte[100];
dataSite = Encoding.ASCII.GetBytes(nameSite);
client.Send(dataSite, dataSite.Length, SocketFlags.None);
Console.WriteLine("NameSite send");
success = true;
}
catch (SocketException e)
{
success = false;
Console.WriteLine("Unable to connect to the server : " + e.StackTrace);
}
return success;
}
I try to reconnect as follows in the catch, count is incrementing with each iteration of a while loop.
if (count % 20 == 0)
{
try
{
if (OpenConnection(siteName))
connected = true;
EventLog.WriteEntry("Connection re-established.");
}
catch (SocketException socketEx)
{
Console.WriteLine("Reconnection failed. Storing data locally. \n\n " + socketEx);
EventLog.WriteEntry("Reconnection failed. Storing data locally. \n\n " + socketEx);
}
}
The constructor simply initialises the IP and Port No. Why is it that certain types of disconnect prevent me from reconnecting without a restart, any ideas?
Do you ever call Dispose() on client to clean it up?
Try adding the call to Dispose() before you null out the client in your OpenConnection method
client.Dispose();
client = null;
After looking at the documentation for Socket on the MSDN, the Disconnect method seems like it also might solve your problem. However, I'm not sure where in your code it should go since the question shows a portion of the logic.
While testing my Client-Server program, I encountered a weird exception when trying to connect to the server on a different router:
"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."
The client can connect to the server perfectly in the local network, however it doesn't work when it is over the internet.
I port forwarded port 1250 (the one I'm using), and using SimplePortForwarding (http://www.simpleportforwarding.com/) I verified that the port was open and working.
I based my implementation on this tutorial:
http://www.developerfusion.com/article/3918/socket-programming-in-c-part-1/
Any idea what is wrong?
Thanks!
Here is the server listen method:
public void startListening(int port)
{
lock(_locker)
{
_listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
// Bind socket to local endpoint, and listen for incoming connections
IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Any, port);
_listeningSocket.Bind(ipEndpoint);
_listeningSocket.Listen(10);
waitForNewClient();
// successfully started listening
_isListening = true;
} catch (SocketException e)
{
// failed for some strange reason
_isListening = false;
}
}
}
Here is the client connect code:
public String connect(String ipAddress, int port)
{
lock(_locker)
{
if (!_connecting)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(ipAddress), port);
try
{
_socket.Connect(endpoint);
_connected = true;
waitForData();
_eventManager.queueEvent(new PlayerJoinedEvent(PlayerJoinedEvent.PLAYER_JOINED, name));
} catch (SocketException e)
{
// Exception is thrown HERE
return e.Message;
}
}
}
return "";
}
Make it sure that your Server IP address is public unless it is not reachable.
Check this link for private address spaces.
You opened port 1250 on the server or the client router? It needs to be opened on the server router. You may need to make sure your server is connected to your DMZ port and/or have DMZ enabled on your server router.
Hope this helps.
I Fixed the problem.
The IP Address I used was the internal ip address I got from ipconfig, but the IP address I needed to use was the external one, the one you get from services like http://www.whatsmyip.org/.
I'm still confused as to why these two numbers are different.