Communication between STM32 and C# via ESP8266 - c#

I'm now trying to connect STM32F429 to C# desktop application with ESP8266(in STA mode). I want ESP8266 to be a client and C# to be a Server. However ESP8266 remains failing to find my PC in the same LAN.
Now I have succeeded to use AT command to connect ESP8266 to my Router AP. And I used XAMPP to open a gate on my PC whose address is 192.168.1.11:80, then use the following command (AT+CIPSTART=\"TCP\",\"192.168.1.11\",80") to successfully connect ESP8266 to it(It returned OK to my STM32F429).
Then I wanna replace XAMPP with my C# code to open a TCP server. But I couldn't make it!
As for the C# Code, I have successfully build a connection between two C# programs (The IP Address is 192.168.1.11:80 which is the same as the one mentioned above).But when I tried to use ESP8266 to connect to the same IP and Port, it failed.
I suspected that there might be some wrong conceptions I have got about opening a TCP Listener on certain port in my LAN... I don't know...
The following is my C# code. (The code of STM32 is just a basic Usart code which I won't present here.)
// Code for Server
namespace Tcp_Server
{
public partial class Form1 : Form
{
private TcpListener myListener;
private TcpClient newClient;
public BinaryReader br;
public BinaryWriter bw;
public Form1()
{
InitializeComponent();
Thread myThread = new Thread(ServerA);
myThread.Start();
}
private void ServerA()
{
IPAddress SvrIP = new IPAddress(Dns.GetHostByName(Dns.GetHostName()).AddressList[0].Address); // Get the virtual IP of my PC.
this.Invoke(new AddToTextbox_dg(AddToTextbox), new object[] { tb_ServerStatus, ip.ToString() });
myListener = new TcpListener(ip, 80); //construct a Tcp Listener.
myListener.Start(); //Tcp Listener start
newClient = myListener.AcceptTcpClient();// Searching for a client...
this.Invoke(new AddToTextbox_dg(AddToTextbox), new object[] { tb_ServerStatus, "Connect Successfully" });
while (true)
{
try
{
NetworkStream clientStream = newClient.GetStream();
br = new BinaryReader(clientStream);
string receive = null;
receive = br.ReadString();//读取
this.Invoke(new AddToTextbox_dg(AddToTextbox), new object[] { tb_ServerStatus, receive });
}
catch
{
MessageBox.Show("Receving failed...");
}
}
}
// Code for client
namespace Client
{
public partial class Form1 : Form
{
private TcpClient client;
public BinaryReader br;
public BinaryWriter bw;
public Form1()
{
InitializeComponent();
Thread myThread = new Thread(ClientA);
myThread.Start();
}
private void ClientA()
{
IPAddress ip = new IPAddress(Dns.GetHostByName(Dns.GetHostName()).AddressList[0].Address); // Get the virtual IP of my PC.
client = new TcpClient(ip.ToString(), 80);
this.Invoke(new AddToTextbox_dg(AddToTextbox), new object[] { tb_ServerStatus, "Connect to Server Successfully!" });
while (true)
{
try
{
NetworkStream clientStream = client.GetStream();
br = new BinaryReader(clientStream);
string receive = null;
receive = br.ReadString();
}
catch
{
MessageBox.Show("Receving failed...");
}
}
}
private void AddToTextbox(TextBox txt, String s)
{
txt.Text += s;
}
private delegate void AddToTextbox_dg(TextBox txt, String s);
private void btn_send_Click(object sender, EventArgs e)
{
NetworkStream clientStream = client.GetStream();
bw = new BinaryWriter(clientStream);
bw.Write(message.Text);
}
}
}
Could somebody please help me with this problem ?
I wonder why I cannot connect ESP8266 to the TcpListener I built on my PC with C#.
What did my PC do when receiving the command:
myListener = new TcpListener(ip, 80);
This project I'm doing is about to transmit the image data I got with Stm32F429 and OV7725 to my PC through ESP8266. I know Usart will be too slow to do that, but now I'm just trying to build the connection. Is there any suggestion you guys could give me about this?

First, make sure no other application on your pc is listening to port 80. if so, you have to change it.
Second, try setting the ip of the TCPListener to local host "127.0.0.1". you will be able to reach this server by connecting to the ip of your PC.

I have checked the used IP in command window as below:
Command Window for checking IP usage
And I remain the IP address which ESP8266 will try to access to be 192.168.1.11:1900 which is the virtual IP of my PC in the LAN as below:
Address ESP8266 try to access
And change the IP C# will try to create a TCPListener on:
C# code
Is this what you mean? Thank you.

Related

Send UDP Broadcast on RasPi 3

I need to send a UDP broadcast from a RaspberryPi 3 running Windows 10 IoT Core. My code so far:
internal class UdpInterface : IDisposable
{
private UdpClient udpClient;
internal UdpInterface(int localPort)
{
udpClient = new UdpClient(localPort);
udpClient.EnableBroadcast = true;
}
internal void BroadcastMessage(string message, int targetPort)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, targetPort);
byte[] bytes = Encoding.ASCII.GetBytes(message);
udpClient.Send(bytes, bytes.Length, ip);
}
public void Dispose()
{
udpClient.Close();
udpClient.Dispose();
}
}
I call it like this from a GPIO pin ValueChanged event:
_udp.BroadcastMessage("Video" + PinMapper(sender.PinNumber), _port);
I tried setting the Internet (Client & Server) capability in package.appxmanifest, and I tried using the DatagramSocket class before.
Do I need some other permissions/capabilities or is something wrong with my code? It did work when sending to target IPs before.
I'm verifying the packet with PacketSender on my dev machine.

C# server.AcceptTcpClient and Listbox

I'm writing a simple TCP-Connection software.
Firstly, I wrote the server in a ConsoleApp and it workes quite well.
Now I wanted to port it to a form application, but when a client connects, it does not add a new entry in my ListBox, on the Console it workes well.
I tried to write in the Load function as well as writing it in a separate Thread.
Both don't work.
In the Console it worked like this, and the Console wrote "User connected":
static void Main(string[] args)
{
const int PORT = 14758;
TcpListener server = new TcpListener(IPAddress.Any, PORT);
try
{
server.Start();
Console.WriteLine("Server started");
} catch (Exception Ex)
{
Console.WriteLine("Error", Ex);
}
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("User connected");
Now in my form App it does not work like this:
public frmMainServer()
{
InitializeComponent();
Thread serverStart = new Thread(new ThreadStart(start_Server));
serverStart.Start();
serverStart.Join();
TcpClient client = server.AcceptTcpClient();
addItem("User connected");
}
As said before, I tried to write the last 2 lines in the Thread, too, but it didn't help.
I actually think I CAN connect to the server, so why does it not add the line?
addItem function:
private void addItem(string item)
{
_items.Add(item);
listStatus.DataSource = _items;
}

Can't receive Broadcasts in WinRT

I'm trying to receive a broadcast via DatagramSockets in WinRT/C#, but I just don't receive a packet.
To be more specific, this is my code:
public sealed partial class MainPage : Page
{
public MainPage(){
this.InitializeComponent();
}
private DatagramSocket listener;
async private void Loaded(object sender, RoutedEventArgs e) {
listener = new DatagramSocket();
listener.MessageReceived += MessageReceived;
await listener.BindServiceNameAsync("50011");
}
private void MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) {
txtText.Text = "Win :D:D:D:D:D:D:D"; //Breakpoint here
}
}
The program never reaches the breakpoint.
I've set all the correct rights/permissions in the appxmanifest.
The program which sends the broadcast is the following one:
static void Main(string[] args) {
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 50011);
string hostname = Dns.GetHostName();
byte[] data = new byte[1];
data[0] = 129;
while (true) {
sock.SendTo(data, iep);
Console.WriteLine("Daten gesendet: {0}", data[0]);
Thread.Sleep(1000);
}
}
I know this program works, because I tested it with another little C# programm on the same PC (but not with WinRT functionality, just normal C#). Also it can't be a Firewall- or Routing Problem, because it, as I just mentioned, already worked with a normal C# program (but I already tried turning the firewall off).
I'm currently trying it on a Wifi-Network using Windows 8.1 and have x64 Processor.
Am I missing something? Is it even possible?
I hope somebody of you can help me
(PS: I know it's pretty similar to this post: Can't Receive UDP Windows RT but there hasen't been progress for more than a year so ...)
I solved it.
You just have to send the broadcasts from a different device.
However it doesn't like broadcasts sent from the same device ....

Winforms server socket application

I'm trying to create a winforms application that listens for traffic on port 10000, and basically works as a middle man for a client application and a remote database. It should have a listen and accept thread which opens a separate client thread when a client connects. This client thread would then handle communication with the client program. The listener application has two listboxes with information on the user that is connecting and the action that is being performed.
For now, I'm trying to use the example program Microsoft gives here and modify it according to my needs, but if anyone has any suggestions on where else I might look I'd love to hear it.
As I try to stumble through this, one thing I haven't been able to figure out yet is how to get this listener going without locking down my computer. Here is my form code (including an exit button and a button that clears my listboxes):
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void btnExit_Click(object sender, EventArgs e) {
this.Close();
}
private void btnClearList_Click(object sender, EventArgs e) {
this.lbActionLog.Items.Clear();
this.lbUserLog.Items.Clear();
count = 0;
this.txtCount.Text = count.ToString();
}
private void Form1_Load(object sender, EventArgs e) {
Server begin = new Server();
begin.createListener();
}
}
and here is my listener code that is called with begin.createListener:
int servPort = 10000;
public void createListener() {
// Create an instance of the TcpListener class.
TcpListener tcpListener = null;
IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
string output = "";
try {
// Set the listener on the local IP address and specify the port.
//
tcpListener = new TcpListener(ipAddress, servPort);
tcpListener.Start();
output = "Waiting for a connection...";
}
catch (Exception e) {
output = "Error: " + e.ToString();
MessageBox.Show(output);
}
while (true) {
// Always use a Sleep call in a while(true) loop
// to avoid locking up your CPU.
Thread.Sleep(10);
// Create socket
//Socket socket = tcpListener.AcceptSocket();
TcpClient tcpClient = tcpListener.AcceptTcpClient();
// Read the data stream from the client.
byte[] bytes = new byte[256];
NetworkStream stream = tcpClient.GetStream();
stream.Read(bytes, 0, bytes.Length);
SocketHelper helper = new SocketHelper();
helper.processMsg(tcpClient, stream, bytes);
}
}
Right now, this just stops on tcpListener.AcceptSocket. The form never loads, and obviously the listboxes aren't being populated. How can I get this listener going automatically with the start of the application, and still load the form and update the listboxes? I want this application to start and be ready at any time to accept a connection, without needing to have one already sitting there waiting.
You are using a blocking method so that the Form1_Load never ends because it awaits incoming connections.
A simple workaround could be to start a new thread that handles connections:
private void Form1_Load(object sender, EventArgs e) {
new Thread(
() =>
{
Server begin = new Server();
begin.createListener();
}
).Start();
}

UDP Tracker not responding

Alright, so I'm trying to connect to UDP trackers using c#, but I never get a response. I also don't get any errors. Here's my code.
namespace UDPTester
{
class MainClass
{
public static bool messageReceived = false;
public static Random Random = new Random();
public static void LOG(string format, params object[] args)
{
Console.WriteLine (format,args);
}
public static void Main (string[] args)
{
LOG ("Creating Packet...");
byte[] packet;
using(var stream = new MemoryStream())
{
var bc = new MiscUtil.Conversion.BigEndianBitConverter();
using(var br = new MiscUtil.IO.EndianBinaryWriter(bc,stream))
{
LOG ("Magic Num: {0}",(Int64)0x41727101980);
br.Write (0x41727101980);
br.Write((Int32)0);
br.Write ((Int32)Random.Next());
packet = stream.ToArray();
LOG ("Packet Size: {0}",packet.Length);
}
}
LOG ("Connecting to tracker...");
var client = new System.Net.Sockets.UdpClient("tracker.openbittorrent.com",80);
UdpState s = new UdpState();
s.e = client.Client.RemoteEndPoint;
s.u = client;
StartReceiving(s);
LOG ("Sending Packet...");
client.Send(packet,packet.Length);
while(!messageReceived)
{
Thread.Sleep(1000);
}
LOG ("Ended");
}
public static void StartReceiving(UdpState state)
{
state.u.BeginReceive(ReceiveCallback,state);
}
public static void ReceiveCallback(IAsyncResult ar)
{
UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u;
IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e;
Byte[] receiveBytes = u.EndReceive(ar, ref e);
string receiveString = Encoding.ASCII.GetString(receiveBytes);
LOG("Received: {0}", receiveString);
messageReceived = true;
StartReceiving((UdpState)ar.AsyncState);
}
}
public class UdpState
{
public UdpClient u;
public EndPoint e;
}
}
I was using a normal BinaryWriter, but that didn't work, and I read somewhere that it wants it's data in BigEndian.
This doesn't work for any of the UDP trackers I've found, any ideas why I'm not getting a response? Did they maybe change the protocol and not tell anyone? HTTP trackers all work fine.
Trackers I've tried
udp://tracker.publicbt.com:80
udp://tracker.ccc.de:80
udp://tracker.istole.it:80
Also, I'm not interested in using MonoTorrent(and when I was using it, the UDP didn't work anyways).
Protocol Sources
http://xbtt.sourceforge.net/udp_tracker_protocol.html
http://www.rasterbar.com/products/libtorrent/udp_tracker_protocol.html
UDP is a connectionless protocol, so you won't see any errors if packets are lost or dropped at the destination.
Try following diagnostic steps:
Use packet sniffer (Wireshark is a good one) to check that UDP packets are leaving the machine.
Install some working BitTorrent client, check if it can communicate with the tracker and if yes, use packet sniffer to see how the packets sent by the working client differ from the packets your code generates.
If working client also can not communicate with the tracker, but the UDP traffic is leaving your machine, the UDP packets are likely dropped by a firewall. You can try 'traceroute' tool to diagnose where your packets are dropped (this is not always 100% reliable, because sometimes firewalls drop UDP packets generated by traceroute and do not drop normal UDP traffic).

Categories

Resources