Arduino web client class not working - c++

I am trying to use the Arduino client class to fetch an HTML page from the Internet (example from the Arduino library itself), but it's not working (connection is not getting established).
It's failing at:
client.connect();
I have tried both Ethernet and Ethernet2 libraries.
My Arduino development platform version is 0017, OS is Windows XP.
Following is my code and configurations inline:
#include <Client.h>
#include <Ethernet2.h>
// #include <Ethernet.h>
#include <Print.h>
#include <Server.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,7 };
byte server[] = { 74,125,47,103 }; // Google home page
byte gateway[] = { 192,168,1,1 };
byte mask[] = { 255,255,255,0 };
Client client(server, 80);
void setup()
{
Ethernet.begin(mac, ip, gateway, mask);
Serial.begin(9600);
delay(1000);
Serial.println("connecting...");
if (client.connect()) {
Serial.println("connected");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
} else {
Serial.println("connection failed");
}
}
void loop()
{
if (client.available()) {
char c = client.read();
Serial.print(c);
}
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;;);
}
}

I don't know the reason but I had to modify the following setup() function to get the code working:
void setup() {
Ethernet.begin(mac, ip, gateway, mask);
Serial.begin(9600);
delay(1000);
Serial.println("connecting...");
for(int i = 0;i <100 ; i++) {
if (client.connect()) {
Serial.println("connected");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
break;
} else {
Serial.println("connection failed");
}
}
}
The code:
client.connect()
does fail twice or thrice but eventually it connects to google web server as well as my local web server in the 3rd or 4th iteration of the 'for' loop.
If anyone knows the reason for such behavior, please reply.

Related

boost::asio - can't set keepalive value

I have copied the chat-example from the boost examples.
server code:
https://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/chat/chat_server.cpp
chat_message.hpp: https://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/chat/chat_message.hpp
client code: https://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/chat/chat_client.cpp
In chat_server.cpp, I have added a cout in chat_room::leave to get notified when a client leaves. In chat_server, I tried to configure TCP keepalive according to this SO answer:
// additional includes that I have added
#include <winsock2.h>
#include <ws2tcpip.h>
#include <ws2spi.h>
#include <mstcpip.h>
#include <windows.h>
// ----
class chat_server {
public:
chat_server(boost::asio::io_service& io_service,
const tcp::endpoint& endpoint)
: acceptor_(io_service, endpoint),
socket_(io_service) {
do_accept();
}
private:
void do_accept() {
acceptor_.async_accept(socket_,
[this](boost::system::error_code ec) {
if(!ec) {
unsigned long val = 1;
int res = setsockopt(socket_.native_handle(), SOL_SOCKET, SO_KEEPALIVE, (char*) &val, sizeof val);
if(res) std::cout << "Can't set sockopt!" << std::endl;
tcp_keepalive alive;
alive.onoff = TRUE;
alive.keepalivetime = 1000;
alive.keepaliveinterval = 1000;
DWORD bytes_ret = 0;
res = WSAIoctl(socket_.native_handle(), SIO_KEEPALIVE_VALS, &alive, sizeof(alive), NULL, 0,
&bytes_ret, NULL, NULL);
if(res) std::cout << "Can't set TCP keepalive!" << std::endl;
std::make_shared<chat_session>(std::move(socket_), room_)->start();
}
do_accept();
});
}
tcp::acceptor acceptor_;
tcp::socket socket_;
chat_room room_;
};
My test setup is to run the server on my local machine. The client runs on a "VMware Workstation 15 Player"-virtual machine, where NAT is used as network adapter. When I connect to the server and uncheck the "Connected"-checkbox in Virtual Machine Settings (should be the same as unplugging the network cable), I would expect to see the output of chat_room::leave in the console, but it seems, that the server even after a few minutes thinks that the client is still connected.
How can I configure the TCP keepalive appropriately? (I would prefer a cross-platform solution which works on Linux too, but if it works on windows, it's better than nothing)
Edit: I have monitored the sent data with Wireshark and found out that no keep-alive packets were sent. What could cause this?

Sockets with QT

How do I send data over sockets in C++ in QT ?
Here's my attempt, it does not work, regards
the server side that sends a file
void MainWindow::on_pushButton_clicked()
{
QString url("127.0.0.1");
sock.bind(QHostAddress(url), 1440);
sock.connectToHost("127.0.0.1", 1440);
sock.write("Coucou");
sock.close();
}
and the client that receives the file
void MainWindowClient::checker() {
csock.connectToHost("127.0.0.1", 1440);
char *datas;
sock.read(datas, 10000000);
ui->label->setText(datas);
csock.close();
}
When i run the program, it does not display "Coucou" as the label set on the client, why ?
Are you forced to use Sockets or can you use Websockets too? If so, Qt has a wonderful way to deal with Websockets and Signals / Slots.
For example, here's what I use for my Remote Control App on my smartphone to control my Music Player (the code has been truncated). But the server can also send commands to synchronize the UI on the smartphone.
The client:
RemoteClient::RemoteClient(CoverProvider *coverProvider, QObject *parent)
: QObject(parent)
, _socket(new QWebSocket("remote", QWebSocketProtocol::VersionLatest, this))
{
connect(_socket, &QWebSocket::textMessageReceived, this, &RemoteClient::processTextMessage);
}
/// Direction: Remote App is receiving orders from Server
void RemoteClient::processTextMessage(const QString &message)
{
if (message.isEmpty()) {
return;
}
QStringList list = message.split(QChar::Null);
if (list.size() <= 1) {
return;
}
int command = list.first().toInt();
switch (command) {
case CMD_Playback:
// Nothing
break;
case CMD_State: {
QMediaPlayer::State state = (QMediaPlayer::State) list.at(1).toInt();
if (state == QMediaPlayer::PlayingState) {
emit playing();
} else if (state == QMediaPlayer::PausedState) {
emit paused();
} else {
emit stopped();
}
break;
}
case CMD_Track:
/// etc.
break;
}
/// etc.
default:
break;
}
}
/// Direction: Remote App is sending orders to Server
void RemoteClient::setVolume(qreal v)
{
QStringList args = { QString::number(CMD_Volume), QString::number(v) };
_socket->sendTextMessage(args.join(QChar::Null));
}
The server:
void RemoteControl::startServer()
{
auto b = _webSocketServer->listen(QHostAddress::Any, _port);
qDebug() << Q_FUNC_INFO << b;
}
void RemoteControl::initializeConnection()
{
/// ...
connect(mediaPlayer(), &MediaPlayer::volumeChanged, this, &RemoteControl::sendVolume);
}
/// Direction: Server to updating Remote App
void RemoteControl::sendVolume(qreal volume)
{
QStringList args = { QString::number(CMD_Volume), QString::number(volume) };
_webSocket->sendTextMessage(args.join(QChar::Null));
}
/// Direction: Remote App is sending command to Server
void RemoteControl::decodeResponseFromClient(const QString &message)
{
if (message.isEmpty()) {
return;
}
QStringList args = message.split(QChar::Null);
if (args.count() < 2) {
return;
}
int command = args.first().toInt();
switch (command) {
case CMD_Volume: {
qreal volume = args.at(1).toFloat();
_currentView->mediaPlayerControl()->mediaPlayer()->setVolume(volume);
break;
}
/// etc.
}
}

TCP Server doesn't receive data correctly [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
The below code has a TCP client in C and TCP Server in Qt C++. My problem is that I am using TCP for reliability, but it has data losses (not packet). In my main code, if I run tcp client to send data, TCP server receives only one packet. if I add sleep(1); to the client between each packet transfer, then TCP server receives data. Both client and server runs on the same computer.
To simplify the question and can't put too huge code here, I have the below code that performs faster, but it losses last 10-15 bytes of the packet.
TCP C client
main.c
#include "socket_handler.h" //I didn't put the all includes here
#define PORT 22208
//tcp server
int main(void)
{
int sockfd;
uint32_t senderAddress = 2130706433; //127.0.0.1
if( connect_to_server_w_uint( &sockfd, senderAddress, PORT ) < 0 ){
printf("error at line 454\n");
exit(1);
}
char data[] = "124b00068c158f$321$52712304$13.212779$0$O$0$0$b4$1$0$3$0$0$0$0$11$0$7$0$1$fe$f1$aaa9fffffffffd80$2132b00$eb460b5e$1$1$2016-02-22 03:01:00$0000-00-00 00:00:00$321$24754$321$13132$1$98$0$5.1$0$3c$64$1$96$4d$3e8$38$2$46$dc$4$3$f6$e6$17$0$e6$d3$1$0$e6$d3$2$0£";
char buffer[512];
int i=0;
for(i=0; i<1000; i++){
bzero(buffer, 512);
sprintf(buffer, "%d***%s -----",i,data);
send_data_to_server(&sockfd, buffer, strlen(data) +1 );
printf("[%d]: data is sent\n", i);
}
close_connection(&sockfd);
return 0;
}
socket_handler.c
int connect_to_server(int *sockfd , struct in_addr senderAddress, uint16_t destPort){
struct sockaddr_in serv_addr;
*sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (*sockfd < 0)
//error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr = senderAddress;
serv_addr.sin_port = htons(destPort);
if (connect( *sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){
printf("connection error line 1413\n");
close( *sockfd );
return -1;
}
return 0;
}
int connect_to_server_w_uint(int *sockfd, uint32_t senderAddress, uint16_t destPort){
struct sockaddr_in serv_addr;
*sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (*sockfd < 0){
printf("ERROR opening socket");
close(*sockfd);
return -1;
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(senderAddress);
serv_addr.sin_port = htons(destPort);
if (connect(*sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{
printf("ERROR connecting");
close(*sockfd);
return -1;
}
return 0;
}
int send_data_to_server(int *sockfd, char *message, uint16_t msgLength){
int n = write(*sockfd, message, msgLength);
if (n < 0){
printf("ERROR writing to socket");
return -1;
}
return 0;
}
int close_connection(int *sockfd){
close( *sockfd );
return 0;
}
Qt C++ TCP Server
MainWindow.cpp
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void ParseThePacket(QByteArray data);
private:
Ui::MainWindow *ui;
Server *server;
};
Client.h
class Client : public QObject
{
Q_OBJECT
public:
explicit Client(QObject *parent = 0);
public slots:
bool connectToHost(QString host);
bool writeData(QByteArray data);
private:
QTcpSocket *socket;
};
Server.cpp
Server::Server(QObject *parent) : QObject(parent)
{
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
if( server->listen(QHostAddress::Any, PORT) ){
qDebug() << "tcp server started!";
}else{
qDebug() << "tcp server couldn't start listening";
}
}
void Server::newConnection()
{
qDebug() << "new connection";
while (server->hasPendingConnections())
{
socket = server->nextPendingConnection();
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
}
}
void Server::disconnected()
{
qDebug() << "disconnected";
socket->deleteLater();
}
void Server::readyRead()
{
qDebug() << "readyRead";
QByteArray buffer = socket->readAll();
emit dataReceived(buffer);
}
Here is an example output from the TCP server(the end of qDebug() output):
00:00:00$321$24754$321$13132$1$98$0$5.1$0$3c$64$1$96$4d$3e8$38$2$46$dc$4$3$f6$e6$17$0$e6$d3$1$0$e6$d3$996***124b00068c158f$321$52712304$13.212779$0$O$0$0$b4$1$0$3$0$0$0$0$11$0$7$0$1$fe$f1$aaa9fffffffffd80$2132b00$eb460b5e$1$1$2016-02-22
03:01:00$0000-00-00
00:00:00$321$24754$321$13132$1$98$0$5.1$0$3c$64$1$96$4d$3e8$38$2$46$dc$4$3$f6$e6$17$0$e6$d3$1$0$e6$d3$997***124b00068c158f$321$52712304$13.212779$0$O$0$0$b4$1$0$3$0$0$0$0$11$0$7$0$1$fe$f1$aaa9fffffffffd80$2132b00$eb460b5e$1$1$2016-02-22
03:01:00$0000-00-00
00:00:00$321$24754$321$13132$1$98$0$5.1$0$3c$64$1$96$4d$3e8$38$2$46$dc$4$3$f6$e6$17$0$e6$d3$1$0$e6$d3$998***124b00068c158f$321$52712304$13.212779$0$O$0$0$b4$1$0$3$0$0$0$0$11$0$7$0$1$fe$f1$aaa9fffffffffd80$2132b00$eb460b5e$1$1$2016-02-22
03:01:00$0000-00-00
00:00:00$321$24754$321$13132$1$98$0$5.1$0$3c$64$1$96$4d$3e8$38$2$46$dc$4$3$f6$e6$17$0$e6$d3$1$0$e6$d3$999***124b00068c158f$321$52712304$13.212779$0$O$0$0$b4$1$0$3$0$0$0$0$11$0$7$0$1$fe$f1$aaa9fffffffffd80$2132b00$eb460b5e$1$1$2016-02-22
03:01:00$0000-00-00
00:00:00$321$24754$321$13132$1$98$0$5.1$0$3c$64$1$96$4d$3e8$38$2$46$dc$4$3$f6$e6$17$0$e6$d3$1$0$e6$d3$"
disconnected
Question 1
Comparing to the original message, it misses "1$0$e6$d3$2$0£" part of the (14 byte) sent data. What is the reason of the missing message? How to fix the code that the TCP server receives the complete data.
Question 2
As I mentioned in the beginning that I am using the same code as a part of a large code and TCP server receives packets when I put sleep(1) between each packet transmission (otherwise it receives only the first packet). What is the reason of it and how to solve it?
I observed the packet transmission on Wireshark that all the TCP packets are sent successfully, but it seems like the receive part has an issue.
I am using Ubuntu 15.04, kernel 3.19.0-69-generic, gcc version 4.9.2
int n = write(*sockfd, message, msgLength);
if (n < 0){
You are only checking that write() did not return a negative value, indicating an error.
However, a write() to a socket does not guarantee that all requested bytes will be written. write() on a socket may return a positive value, fewer than msgLength here, indicating that fewer than the requested bytes have been written. This is documented, in detail, in write()'s manual page.
You are ignoring this possibility, and that's the likely reason you're missing your data. It's up to you to figure out what to do, in this case. The usual approach is to simply go back and attempt to write the remaining bytes (which, again, may not be written in their entirety).
Similarly, when reading from a socket, you are not guaranteed that everything that was written to the socket, by the sender, will be read in one gulp. It is up to you to verify that your reader has read everything that there is to read, and if the reader expects more data, continue reading from the socket until it is received.
readAll just reads all data available to the current moment.

QWebSocketServer still connecting

I'm writing a simple server that pass some data to javascript by QWebSocketServer (basicly the same as qt doc...).
And, please take a look at here:
void DebuggerServer::onNewConnection() {
puts("C");
QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
connect(pSocket, &QWebSocket::textMessageReceived, this, &DebuggerServer::processMessage);
connect(pSocket, &QWebSocket::disconnected, this, &DebuggerServer::socketDisconnected);
printf("onNewConnection");
m_clients << pSocket;
}
I try to puts("C"); here, but I get nothing.
In my browser (latest version of chrome), If I send a request to the server, i will get some information like socket is connecting.
I've tried these things: closing firewall, changing port, changing browser, changing compile mode.
I'm not sure if this involve this issue, I'm compiling these code by msvc15 and manully moc headers.
This code is inject into other application by loadlibrary.
Full source code for the server is followed...
Server.cpp
#include "Server.h"
#include "Inspector.h"
#include "Server.moc"
#include <QtCore/QCoreApplication>
const int port = 5642;
DebuggerServer *server;
void StartServer() {
server = new DebuggerServer(port);
}
QT_USE_NAMESPACE
DebuggerServer::DebuggerServer(quint16 port, QObject *parent) :
QObject(parent),
m_pWebSocketServer(Q_NULLPTR),
m_clients()
{
m_pWebSocketServer = new QWebSocketServer(QStringLiteral("mvInspector"),
QWebSocketServer::NonSecureMode,
this);
puts("A");
if (m_pWebSocketServer->listen(QHostAddress::Any, port))
{
puts("B");
connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
this, &DebuggerServer::onNewConnection);
}
}
DebuggerServer::~DebuggerServer() {
m_pWebSocketServer->close();
qDeleteAll(m_clients.begin(), m_clients.end());
}
template<class T>
QString toStr(QList<T> y) {
QString rst;
for (T x : y)
rst += "\n" + QString(x);
return rst;
}
#define ASSERT_N(x) if (frame.length() != x) rst = "ERRON, wrong number of arguments."; else
void DebuggerServer::processMessage(QString message) {
QWebSocket *pSender = qobject_cast<QWebSocket *>(sender());
QStringList frame = message.split("\n");
QString rst;
rst += frame[0];
if (frame[0] == "getRootWindows") {
ASSERT_N(1)
rst += toStr(getRootWindows());
}
if (frame[0] == "getChildren") {
ASSERT_N(2)
rst += toStr(getChildren(frame[1].toInt()));
}
if (frame[0] == "getPropertyName") {
ASSERT_N(2)
rst += toStr(getPropertyName(frame[1].toInt()));
}
if (frame[0] == "getProperty") {
ASSERT_N(3)
rst += getProperty(frame[1].toInt(), frame[2].toStdString().c_str()).toBase64();
}
if (frame[0] == "getClassname") {
ASSERT_N(2)
rst += getClassname(frame[1].toInt());
}
if (frame[0] == "getClassname") {
ASSERT_N(2)
rst += getObjectname(frame[1].toInt());
}
printf(rst.toStdString().c_str());
pSender->sendTextMessage(rst);
}
void DebuggerServer::socketDisconnected()
{
QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
if (pClient) {
m_clients.removeAll(pClient);
pClient->deleteLater();
}
printf("socketDisconnected");
}
void DebuggerServer::onNewConnection() {
puts("C");
QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
connect(pSocket, &QWebSocket::textMessageReceived, this, &DebuggerServer::processMessage);
connect(pSocket, &QWebSocket::disconnected, this, &DebuggerServer::socketDisconnected);
printf("onNewConnection");
m_clients << pSocket;
}
Server.h
#pragma once
#include <QtCore/qobject.h>
#include <QtWebSockets/qwebsocketserver>
#include <QtWebSockets/QWebSocket>
void StartServer();
class DebuggerServer : public QObject {
Q_OBJECT
public:
explicit DebuggerServer(quint16 port, QObject *parent = Q_NULLPTR);
virtual ~DebuggerServer();
private Q_SLOTS:
void onNewConnection();
void processMessage(QString message);
void socketDisconnected();
private:
QWebSocketServer *m_pWebSocketServer;
QList<QWebSocket *> m_clients;
};
DLLMain
#include <Windows.h>
#include "../Server.h"
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
StartServer();
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
Finally, it seems to be a bug of Qt 5.4.1 at least on windows 10 (msvc) .
I can make two Qt application connecting by the websocket, but cannot let At application connecting with a normal browser.
So, I use another websocket library and repect the original Qt websocket.

QThread wiringPi GPIO

I use a RaspberryPi and Qt for my Qt for my embedded Project
I have read about QThread. I tested QThread and it is working very fine.
I want to control some GPIO pins in my Thread, but this doesn't work
My GPIO pins are working, I have tested it.
Here my Code:
class referenz_thread:public QThread
{
Q_OBJECT
public:
bool x_isRef;
bool y_isRef;
void run()
{
x_isRef = false;
y_isRef = false;
digitalWrite(x_treiber,1);
digitalWrite(y_treiber,1);
digitalWrite(x_richtung,0);
digitalWrite(y_richtung,1);
while(1)
{
if(digitalRead(x_end) == 0)
{
digitalWrite(x_treiber,0);
x_isRef = true;
}
if(digitalRead(y_end) == 0)
{
digitalWrite(y_treiber,0);
y_isRef = true;
}
if((x_isRef == true) && (y_isRef == true))
{
break;
}
digitalWrite(x_v,1);
digitalWrite(y_v,1);
delay(1);
digitalWrite(x_v,0);
delay(1);
digitalWrite(x_v,1);
delay(1);
digitalWrite(x_v,0);
digitalWrite(y_v,0);
delay(1);
}
}
public slots:
};
This is in MainWindow.cpp
referenz_thread *ref_thread = new referenz_thread();
connect(ui->btn_ref,SIGNAL(clicked()),ref_thread,SLOT(start()));
I have wiringPiSetup already executed in my MainThread.