SFML, how to send SoundBuffer with a packet? - sfml

I am trying to create a voice chat using SFML.
Program records 1 second-long parts with a SoundbufferRecorder.
when I test the code below, console shows this:
Failed to load sound file from memory
void receiveData()
{
received_data = false;
unsigned short port;
if (serwer) port = s_port;
else port = k_port;
Packet p;
socket.receive(p, ip, port);
bufferfrommemory.loadFromMemory(p.getData(), p.getDataSize());
received_data= true;
}
void sendData()
{
unsigned short port;
if (serwer) port = k_port;
else port = s_port;
const sf::SoundBuffer& buffer = recorder.getBuffer();
const sf::Int16* samples = buffer.getSamples();
std::size_t count = buffer.getSampleCount();
Packet p;
p.append(samples, count);
socket.send(p, ip, port);
}
void playIt()
{
Sound g;
g.setBuffer(bufferfrommemory);
g.play();
}
Thanks in advance for any help.

Related

I want to run a websocket server with mongoose how do I solve the error?

https://github.com/cesanta/mongoose/blob/master/examples/websocket-server/main.c
#include "mongoose.h"
static const char *s_listen_on = "ws://localhost:80020";
static const char *s_web_root = ".";
// This RESTful server implements the following endpoints:
// /websocket - upgrade to Websocket, and implement websocket echo server
// /api/rest - respond with JSON string {"result": 123}
// any other URI serves static files from s_web_root
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_OPEN) {
// c->is_hexdumping = 1;
} else if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
if (mg_http_match_uri(hm, "/websocket")) {
// Upgrade to websocket. From now on, a connection is a full-duplex
// Websocket connection, which will receive MG_EV_WS_MSG events.
mg_ws_upgrade(c, hm, NULL);
} else if (mg_http_match_uri(hm, "/rest")) {
// Serve REST response
mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123);
} else {
// Serve static files
struct mg_http_serve_opts opts = {.root_dir = s_web_root};
mg_http_serve_dir(c, ev_data, &opts);
}
} else if (ev == MG_EV_WS_MSG) {
// Got websocket frame. Received data is wm->data. Echo it back!
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT);
}
(void) fn_data;
}
int main(void) {
struct mg_mgr mgr; // Event manager
mg_mgr_init(&mgr); // Initialise event manager
printf("Starting WS listener on %s/websocket\n", s_listen_on);
mg_http_listen(&mgr, s_listen_on, fn, NULL); // Create HTTP listener
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
mg_mgr_free(&mgr);
return 0;
}
I want to create a websocket server, but I am getting an error while running this project.
I tried on different ports but the result did not change.
Error is:
mongoose.c:2774:mg_listen Failed: ws://localhost:80020, errno 0
Failed

Qt UDpsocket working on same computer but not on two computers on same network

I am able to send and receive to two different programs running on same computer. But not able to do the same when running them on different computers. Both computers are on same Local area network. I am working on windows 10.
#include "communicationmanager.h"
communicationManager::communicationManager(int portNumber,int socketRole)
{
//socketRole:0=Sender 1=Reciever
//socket = new QUdpSocket(this);
PortNumber = portNumber;
socket = new QUdpSocket(this);
if(socketRole == 1)
{
socket->bind(QHostAddress::LocalHost,PortNumber);
connect(socket, SIGNAL(readyRead()), this, SLOT(recieve()));
}
}
communicationManager::~communicationManager()
{
//delete socket;
}
void communicationManager::prepareMessage(QString command,QString message,int recieverID)
{
Command = command;
Message = message;
recieverID = recieverID;
}
void communicationManager::send()
{
QByteArray datagram;
QDataStream out(&datagram, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_13);
out<<Command<<Message<<recieverID;
socket->writeDatagram(datagram, QHostAddress::LocalHost, PortNumber);
}
void communicationManager::recieve()//For recieving data
{
qDebug()<<"recieve";
QByteArray datagram;
do
{
datagram.resize(socket->pendingDatagramSize());
socket->readDatagram(datagram.data(), datagram.size());
} while (socket->hasPendingDatagrams());
QDataStream in(&datagram, QIODevice::ReadOnly);
QString command;
QString message;
int recieverID;
in >>command>>message>>recieverID;
}
You need to bind to QHostAddress::Any in order to actually receive packets from outside the local machine. QHostAddress::LocalHost will only receive traffic from the same physical machine.

Getting [e][wifigeneric.cpp:739] hostbyname(): dns failed when performing POST request

I am getting started with electronics and microcontrollers programming.
I have made a simple circuit where I use DHT22 sensor to measure temperature and humidity. I have also made my own API in Node and Express (MongoDB as a database). It is very simple API, just two endpoints: one for getting. and one for posting data. I ma able to create succesfull requests using Postman (and with the browser).
Just to be clear, I want to send temperature and humidity to my API, and then do some work with this data on Vue website (I think that this is not relevant at all, but again, just to be clear what I am trying to achieve).
Now I will say what I am using:
Windows 10 OS
NodeMCU ESP32 microcontroller
DHT22 sensor
HTTPClient library (I think this one is causing a problem)
PlatformIO with Arduino.h header file
Everything is ok, but when I try to send data to my database things fail. I am ALWAYS getting following error
[e][wifigeneric.cpp:739] hostbyname(): dns failed
I have tried to make the POST request using both http://localhost:3000/endpoint and http://127.0.0.1/endpoint (that part is really strange, why I am getting DNS error when using IP address without domain name?).
I have already looked up for the solution on the web. I have come across many similar questions on github, but any of them worked for me). Also, none of them were solving error caused by line 739.
Here I will leave my code. Is is simple and short, so I will post all of it. Please, do not blame me for my c++ skills, I am getting better :D
Thank you in advance, have a nice day or evening.
Kind regards, Bartek.
#include <Arduino.h>
#include <DHT.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#define DHTPIN 22
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const char ssid[] = "MY_SSIID";
const char password[] = "MY_WIFI_PASSWORD";
const char apiAddress[] = "http://localhost:3000/reading";
unsigned long lastTime = 0;
unsigned long timerDelay = 60000;
struct sensorReading {
float temperature;
float humidity;
float heatIndex;
};
sensorReading readDataFromSensor();
void sendData(sensorReading * reading);
void setup() {
Serial.begin(9600);
dht.begin();
WiFi.begin(ssid, password);
WiFi.config(IPAddress(192, 168, 1, 223), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0));
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print('.');
}
}
void loop() {
if (millis() > lastTime + timerDelay) {
sensorReading data;
sensorReading * p_data = NULL;
data = readDataFromSensor();
p_data = &data;
sendData(p_data);
}
}
sensorReading readDataFromSensor() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
float heatIndex = dht.computeHeatIndex(temperature, humidity, false);
if (isnan(temperature) || isnan(humidity)) {
return sensorReading {};
}
const sensorReading dataToReturn {temperature, humidity, heatIndex};
return dataToReturn;
}
void sendData(sensorReading * reading) {
using namespace std;
if(WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(apiAddress, 3000);
http.addHeader("Content-Type", "application/json");
DynamicJsonDocument doc(1024);
doc["temperature"] = reading->temperature;
doc["humidity"] = reading->humidity;
doc["heatIndex"] = reading->heatIndex;
String dataToSend;
serializeJson(doc, dataToSend);
int responseCode = http.POST(dataToSend);
Serial.println(responseCode);
http.end();
} else {
Serial.print("Ups...");
}
lastTime = millis();
}
You're calling the begin() method on http with two arguments, which are meant to be a hostname and a port number (and optionally a URI/path). Instead of passing a hostname, you're passing a full URL, which the HTTP client is attempting to resolve as a hostname.
The single argument form of http.begin() does take a URL. The form you're calling does not.
You can confirm this by reading the source code, which allows for these declarations of the begin() method:
bool begin(WiFiClient &client, String url);
bool begin(WiFiClient &client, String host, uint16_t port, String uri = "/", bool https = false);
#ifdef HTTPCLIENT_1_1_COMPATIBLE
bool begin(String url);
bool begin(String url, const char* CAcert);
bool begin(String host, uint16_t port, String uri = "/");
bool begin(String host, uint16_t port, String uri, const char* CAcert);
bool begin(String host, uint16_t port, String uri, const char* CAcert, const char* cli_cert, const char* cli_key);
#endif
A big hint to this problem is that you repeated the port number in both the URL and the second argument to http.begin().
Instead your code should look like either:
http.begin(apiAddress);
or
const char apiName[] = "localhost";
const unsigned apiPort = 3000;
const char apiPath[] = "reading";
...
http.begin(apiName, apiPort, apiPath);
However - this also will not work because localhost and 127.0.0.1 mean "self" or "the same computer". You'll need to provide the real IP address of the server you're trying to reach; localhost and 127.0.0.1 only refer to it when you're running software on it.

ESP32 to ESP32 WiFi Server/Client Problem

I've got one ESP32 acting as client and another ESP32 acting as an access-point for direct communication and outdoor use.
I have set up a server on the AP end and would like the client to communicate with it but I can't seem to make this work.
I would like to know two things:
How do I send or write data to the server from the client?
How do I read and display the data that was sent to the server from the client?
I have attached the code below:
Code for AP/Server
//SERVER
//Load Wi-Fi library
#include <WiFi.h>
// Replace with your network credentials
const char* ssid = "ESP32-Access-Point";
const char* password = "SyedAhmedAli";
//Set web server port number to 80
WiFiServer server(80);
void setup() {
Serial.begin(115200);
Serial.println("Setting AP (Access Point)…");
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address ");
Serial.println(IP);
Serial.print("MAC address ");
Serial.println(WiFi.softAPmacAddress());
server.begin();
}
void loop(){
WiFiClient client = server.available(); //Listen for incoming clients
if (client)
{ //If a new client connects,
Serial.println("New Client."); //print a message out in the serial port
while (client.connected())
{
Serial.println("Client connected.");
Serial.println(client.available());
if (client.available() > 0)
{
// read the bytes incoming from the client:
char thisChar = client.read();
// echo the bytes back to the client:
server.write(thisChar);
// echo the bytes to the server as well:
Serial.write(thisChar);
}
}
client.stop();
Serial.println("Client disconnected.");
Serial.println();
}
}
Code for Client
//Client
#include <WiFi.h>
const char* ssid = "ESP32-Access-Point";
const char* password = "SyedAhmedAli";
WiFiClient client;
IPAddress server(192, 168, 4, 1);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" connected");
if(client.connect(server, 80))
{
Serial.println("connected to server");
client.write("Data");
}
else
{
Serial.println("failed to connect to server");
}
}
void loop()
{
}
Alternatively to the previous answer, you could use espnow as a protocol between various esp32. Here an example.
You must implement some sort of protocol like TCP, UDP to exchange data.
Example Project using TCP
https://www.instructables.com/id/WiFi-Communication-Between-Two-ESP8266-Based-MCU-T/
Example Project using UDP
https://circuits4you.com/2018/01/01/esp-to-esp-communication/
Look at this very handy function:
void SetWifi(const char *name, const char *password) { // Turn on wifi with server
Serial.println("Starting server");
WiFi.disconnect();
WiFi.softAP(name, password);
delay(2000);
IPAddress IP = WiFi.softAPIP();
Serial.print("Server IP : ");
Serial.println(IP);
server.begin();
server.setNoDelay(true);
Serial.println("Server started");
}
You can write data with this function :
void sendDataTCP(String message) { // function to send message back to client
if (client && client.connected()) { //check if client is there
client.println(message);
}
client.flush();
}
Receive data with this function:
void availableMessage() {
if (client.available()) {//check if client is there
while (client.available()) {
String message = client.readStringUntil('\n'); //read string until enter (end of message)
Serial.println("Received: " + message);
message.toCharArray(buffer, BUFFER); // put message in char array (buffer)
client.flush(); // discard all bytes that have been read
}
}
}
Check if someone has connected:
void connectClient() {
if (server.hasClient()) // if server has a client
{
if (client = server.available()) { // if client is connected
Serial.println("Connected");
}
}
}
I think this will get you in the direction of accomplishing your goal, good luck!

Download from tftp server on ubuntu ( boost::asio c++)

I'm looking for an example of an TFTP client running on Linux platform. I'm trying do this problem using boost::asio here's the code:
void packi16 (char *buf, unsigned short int i){ //change the host order to network byte order (16bit)
i = htons(i);
memcpy(buf,&i,2);
}
int main()
{
boost::asio::io_service service;
boost::asio::ip::udp::socket sock(service);
sock.open(boost::asio::ip::udp::v4());
boost::asio::ip::udp::endpoint receiver_ep(boost::asio::ip::address::from_string("127.0.0.1"), 69);
char filename[] = "first";
char mode[] = "netascii";
int filename_size = (sizeof(filename)/sizeof(*filename));
int mode_size = (sizeof(mode)/sizeof(*mode));
char *packet;
packet = (char *)malloc((17)*sizeof(char));
packi16(packet,1); // 1 opcode for read request
memcpy(packet+2,filename,filename_size-1);
memset(packet+1+filename_size, '\0', 1);
memcpy(packet+2+filename_size, mode, mode_size-1);
memset(packet+1+filename_size+mode_size, '\0', 1);
sock.send_to(boost::asio::buffer(packet, 17), receiver_ep);
char buff[512];
boost::asio::ip::udp::endpoint sender_ep;
sock.receive_from(boost::asio::buffer(buff), sender_ep);
std::cout << buff;
return 0;
}
The problem is in program no error but code don't print anything although in the TFTP server i have this file : first. I use sniffer (wireshark) for see what's going on in my request packet, i capture packet made in tftp client in ubuntu then capture my program capture and it seems my program build correct packet.
Thanks m.s., Prabhu for your comments.