How to send data from C# to python using sockets? - c#

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!

Related

Why is my tcp client unable to connect to my server

I am having trouble with my c# tcp code.
When I run the server and the client on the same computer, it will connect just fine.
But when I run the client on a different PC or on a phone, I get: 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.
Here is the server code:
private static void CreateServer()
{
TcpListener server = null;
try
{
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
server = new TcpListener(localAddr, port);
server.Start();
Byte[] bytes = new Byte[256];
String data = null;
while (true)
{
Console.Write("Waiting for a connection... ");
/*
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList;
Console.WriteLine(ipHostInfo.HostName);
Console.WriteLine(ipAddress[0]);
*/
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
NetworkStream stream = client.GetStream();
int i;
try
{
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, msg.Length);
}
}
catch(IOException e)
{
//Console.WriteLine(e);
Console.WriteLine("Restarting Server");
//client.Close();
//CreateServer();
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
//Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
I removed most of the comments. But that is the basic example for a tcp server from the documentation.
the client connect code is very simple:
tcpClient = new TcpClient();
tcpClient.Connect("192.168.0.7", 13000);
with the declaration for tcpClient saved in a less local spot for retaining and quickly reconnecting.
What I have tried:
I have made sure the IP address is correct, I even port forwarded and used my external IP, but got the same issue.
I made sure the firewall is not blocking the app on either device.
I tried using either device as the server.
I've looked up the problem and the only other person to have this issue needed to make sure he put in the correct IP and fix his firewall settings. I'm probably missing something super obvious.
One final piece of information, one device is wired to the router, I don't know if that is messing with anything.
One other thing, I tried:
tcpClient.Connect(new IPEndPoint(IPAddress.Parse("192.168.0.7"), 13000));
as well.
Whelp I was right. It was something very obvious and honestly dumb on my part.
on the server side:
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
does not result in the server listening on its ipv4, instead it listens on an ipv6
so what you want:
Remove the localAddr declaration, as it is not important, and instead of calling:
server = new TcpListener(localAddr, port);
call:
server = new TcpListener(IPAddress.Any, port);
IPAddress.Any is used to listen across all of the network interfaces the device has.

In a project how to set up a "client" console application and a "server" console application

Alright so this might be worded wrong or using the wrong terminology. I want to know how I would set up a console application in my local machine that would be the "server" where it would run all my background tasks/events that happen on the client windows? I would only have one console application for the "server" and up to four "client" console applications.
Each of these would do separate things. The "server" application would just do all the calculations and functions and the client would just show in nice format what I want them to show from the results from the server.
Also I wouldn't know how to set it up in a C# type of project.
For a complete tutorial, I would recommend reading this Code Project article.
For some example code, the following client / server console applications are pulled from the MSDN.
Synchronous Client Socket Example:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class SynchronousSocketClient {
public static void StartClient() {
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
// Connect to a remote device.
try {
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName())
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress,11000);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Connect the socket to the remote endpoint. Catch any errors.
try {
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes,0,bytesRec));
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
} 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());
}
}
public static int Main(String[] args) {
StartClient();
return 0;
}
}
Synchronous Server Socket Example:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class SynchronousSocketListener {
// Incoming data from the client.
public static string data = null;
public static void StartListening() {
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Bind the socket to the local endpoint and
// listen for incoming connections.
try {
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (true) {
Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
data = null;
// An incoming connection needs to be processed.
while (true) {
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes,0,bytesRec);
if (data.IndexOf("<EOF>") > -1) {
break;
}
}
// Show the data on the console.
Console.WriteLine( "Text received : {0}", data);
// Echo the data back to the client.
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static int Main(String[] args) {
StartListening();
return 0;
}
}
To set this up, you would need to create a new solution in Visual Studio, and then add two console application projects to that solution, one for the client and one for the server. Once both projects are completed, you can copy and install the code provided above. Build the solution to generate a .exe file for both client and server. Locate your .exe files, run the server first, and then run the client second. You should see some output on both the server and client console windows.
EDIT: Please bear in mind that this will get you as far as running a server and client locally. When you distribute your server / client code to other machines, you will have to contend with firewalls, port forwarding, and potentially proxies depending on your network.

TcpListener & Socket connection fails

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

Weird C# SocketException

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.

Why is C# triggering a Socket Timeout issue on another machine?

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...

Categories

Resources