Unable to send publish messages from esp8266 to Raspberry (Broker) using MQTT. Getting Socket Error <Random Device Id>, Disconnecting - raspberry-pi

I am trying to send and receive a messages from Raspberry Pi (Broker) to Arduino-ESP8266 (client) using MQTT. What I am trying to achieve is pretty basic for now. The broker sends a start command and the client on receving the message should send back a random number. I am able to read the message sent by the broker but the messages from the client are never sent. Here is the code that I am using
#include <WiFiEsp.h>
#include <WiFiEspClient.h>
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(19, 18); //RX, TX
#endif
#define MQTT_KEEPALIVE 10
#include <PubSubClient.h>
IPAddress server(192, 168, 0, 105);
char ssid[] = "user1956";
char password[] = "******";
int status = WL_IDLE_STATUS; //wifi radio's status
//MQTT
//const char* mqtt_topic = "Rpi_Master";
const char* mqtt_username = "pi";
const char* mqtt_password = "********";
//client Id
const char* clientID = "A_2";
//Variables for numbers
long randNumber1;
String rn1;
char rn1_char[50];
WiFiEspClient wifiClient;
PubSubClient client(wifiClient); //1883 is the listener port for the broker
void setup() {
// Initilize serial for debugging
Serial.begin(115200);
//initilize serial for ESP module
Serial1.begin(115200);
//initilize the ESP module
WiFi.init(&Serial1);
if (WiFi.status() == WL_NO_SHIELD)
{
Serial.println("WiFi shield not present");
while (true);
}
while (status != WL_CONNECTED)
{
Serial.print("Attempting to connect to WPA SSID : ");
Serial.println(ssid);
status = WiFi.begin(ssid, password);
}
Serial.println("You are connected to the network");
client.setServer(server, 1883);
client.setCallback(callback);
//Allow the hardware to sort itself
delay(1500);
randomSeed(50);
}
void callback(char* topic, byte* payload, unsigned int length)
{
Serial.print("Message Received: [");
Serial.print(topic);
Serial.println("]");
Serial.print("Message is:");
String message = (char *)payload;
Serial.println(message);
else if (!strncmp((char *)payload, "B1", length)) //Start code can be changed to any string value in place of 1
{
client.publish("Ad_B", "OK");
generateRandomData();
}
else if (!strncmp((char *)payload, "B2", length)) //Start code can be changed to any string value in place of 1
{
client.publish("Ad_B", "OK");
generateRandomData();
}
}
void loop()
{
if (!client.connected())
{
reconnect();
}
client.loop();
delay(1000);
}
void reconnect()
{
while (!client.connected())
{
Serial.print("Attempting MQTT Connection...");
//Attempt to Connect
if (client.connect(clientID, mqtt_username, mqtt_password))
{
Serial.println("connected");
//Once connected publish an announcement
client.publish("Ad_B", "Ready");
//and resubscribe
client.subscribe("Rpi_Master"); //This name can be changed
}
else
{
Serial.print("failed, rc = ");
Serial.print(client.state());
Serial.println("Trying again in 5 seconds");
//Wait for 5 seconds before retrying
delay(5000);
}
}
}
void generateRandomData(){
randNumber1 = random(0,0); //(14000,15000)
//Serial.println(randNumber1); // print a random number from 0to 299
rn1 = String(randNumber1);
rn1.toCharArray(rn1_char, rn1.length() + 1);
client.publish("LC_B_1", rn1_char);
client.publish("Ad_B", "End");
}
This is the output of the serial monitor that I am receiving:
07:45:42.016 -> [WiFiEsp] Initializing ESP module
07:45:45.430 -> [WiFiEsp] Initilization successful - 1.5.4
07:45:45.430 -> Attempting to connect to WPA SSID : No Free Wifi
07:45:50.464 -> [WiFiEsp] Connected to No Free Wifi
07:45:50.464 -> You are connected to the network
07:45:51.940 -> Attempting MQTT Connection...[WiFiEsp] Connecting to 192.168.0.105
07:45:52.084 -> connected
07:46:31.926 -> Message Received: [Rpi_Master]
07:46:31.926 -> Message is:B2ter
07:46:37.438 -> [WiFiEsp] TIMEOUT: 20
08:20:58.967 -> [WiFiEsp] >>> TIMEOUT >>>
The client is unable to publish any messages. The mosquitto log shows PINGREQ and RINGRESP to a random id and client.publish stops with the following message in the log - Socket Error on Client <Some Random Client Id>, Disconnecting. Attached the screenshot of the log. Is there any way to know what the unknown client is? Please help me to sort this issue. Thanks.

You generateRandom() function blocks (15 seconds) for longer than the keep alive (10 seconds) timeout and this will block the client.loop() function so it will not be able to send keep alive packets.

Related

Using both TCP and UDP protocols seem not to work on Ethernet Shield w5100

I'm having a problem using both TCP and UDP in the same sketch. What appears to happen is that if the same socket is reused for UDP after it was in use for TCP, UPD fails to receive data. I was able to reproduce this with the WebServer example. I've added to it a DNS query once in every 10 seconds to query yahoo.com IP address. The DSN queries succeed if I'm not creating any client traffic from the browser. After I query the server over HTTP over TCP, the DSN queries start to fail. DNS queries are implemented in UDP. This is the code that I'm using:
/*
Web Server
A simple web server that shows the value of the analog input pins.
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
* Analog inputs attached to pins A0 through A5 (optional)
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
modified 02 Sept 2015
by Arturo Guadalupi
*/
#include <SPI.h>
#include <Ethernet.h>
#include <Dns.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
unsigned long t0;
void setup() {
// You can use Ethernet.init(pin) to configure the CS pin
//Ethernet.init(10); // Most Arduino shields
//Ethernet.init(5); // MKR ETH shield
//Ethernet.init(0); // Teensy 2.0
//Ethernet.init(20); // Teensy++ 2.0
//Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet
//Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Ethernet WebServer Example");
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// start the server
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
t0 = millis();
}
void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("<br />");
}
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disconnected");
}
if (millis() - t0 > 10000)
{
DNSClient dns;
dns.begin(IPAddress(8,8,8,8));
IPAddress yahoo;
if (dns.getHostByName("yahoo.com", yahoo) == 1)
{
Serial.print("Yahoo: ");
Serial.print(yahoo[0]);
Serial.print(".");
Serial.print(yahoo[1]);
Serial.print(".");
Serial.print(yahoo[2]);
Serial.print(".");
Serial.println(yahoo[3]);
}
else
{
Serial.println("Failed to query yahoo.com IP address");
}
t0 = millis();
}
}
Is this a known issue? Can someone please help in identifying the problem in my code, or if there is a workaround for this issue? Can it be a hardware issue? I'm using SunFounder boards, not the original Arduino boards.
Thanks a lot,
Boaz,

Running WebServerSecure and PubSubClient on ESP8266

I wrote a sketch for ESP8266. This sketch reads some sensor data and published it via MQTT. In addition I want to let a Web server provide the same data as HTML, or JSON web service.
The MQTT publish is triggered via a TaskScheduler timer.
Both functions, MQTT and Web server, work for itself, but sadly not together. Here's a simplified sketch:
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServerSecure.h>
#include <PubSubClient.h>
#include <TaskScheduler.h>
#include <My_WLAN.h> // provices connection to local WLAN and network settings
const char DNS_NAME[] = "myserver.local";
const int HTTPS_PORT = 443; // HTTPS
const char MQTT_SVR[] = "myserver.local";
const unsigned int MQTT_PORT = 8883; // MQTTS
WiFiClientSecure wifiClient;
PubSubClient mqttClient(wifiClient); // MQTT client instance
ESP8266WebServerSecure server(HTTPS_PORT); // web server instance
void t1Callback(void); // callback method prototypes
Task t1(60000, TASK_FOREVER, &t1Callback); // main loop task
Scheduler timer; // task scheduler
static const uint8_t SVR_FINGERPRINT[20] PROGMEM = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20 };
static const char deviceCert[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
[... certificate ...]
-----END CERTIFICATE-----
)EOF";
static const char deviceKey[] PROGMEM = R"EOF(
-----BEGIN RSA PRIVATE KEY-----
[... key ...]
-----END RSA PRIVATE KEY-----
)EOF";
/* *****************************
MQTT_connect
* *****************************/
void MQTT_connect()
{
int attempt = 0;
/* loop until reconnected */
while (!mqttClient.connected() && attempt < 10) {
attempt++;
Serial.print("Attempting MQTT connection ("); Serial.print(attempt); Serial.print(")...");
mqttClient.setServer(MQTT_SVR, MQTT_PORT);
if (mqttClient.connect(DNS_NAME)) {
Serial.println("success");
} else {
Serial.print("failed, status code = "); Serial.print(mqttClient.state());
Serial.println(". - Try again in 5 seconds...");
delay(5000);
}
}
}
/* *****************************
Web Server handleRoot
* *****************************/
void handleRoot() {
digitalWrite(LED_BUILTIN, LOW); // on
Serial.println("WebServer ROOT");
server.send(200, "text/html", "WebServer ROOT");
digitalWrite(LED_BUILTIN, HIGH); // off
}
/* *****************************
Web Server handleNotFound
* *****************************/
void handleNotFound() {
digitalWrite(LED_BUILTIN, LOW); // on
String message = "File not found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(LED_BUILTIN, HIGH); // off
}
/* *************************
MQTT_publish_something
* *************************/
void MQTT_publish_something() {
digitalWrite(LED_BUILTIN, LOW); // on
char payload[30] = "some_payload_data";
if (!mqttClient.publish("MQTT/Test", payload, true)) { // retain message
Serial.println("MQTT message lost!");
}
digitalWrite(LED_BUILTIN, HIGH); // off
}
/* *************************
t1: main timer (callback)
* *************************/
void t1Callback() {
my.WiFi_connect(); // check and re-connect to WLAN (in My_WLAN.h)
if (WiFi.status() == WL_CONNECTED) {
MQTT_connect();
MQTT_publish_something();
}
}
/* *************************
setup
* *************************/
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // internal LED
digitalWrite(LED_BUILTIN, HIGH); // off
/* -----------------------
open Serial |
----------------------- */
Serial.begin(74880);
while (!Serial); // wait for Serial being ready
/* -----------------------
connect to WLAN |
----------------------- */
my.WiFi_connect(); // this is connecting to WLAN & error handling (in My_WLAN.h)
wifiClient.setFingerprint(SVR_FINGERPRINT);
/* -----------------------
set mDNS |
----------------------- */
if (MDNS.begin(DNS_NAME)) {
Serial.printf("mDNS responder started for %s\n", DNS_NAME);
MDNS.addService("https", "tcp", HTTPS_PORT); // add service to MDNS-SD
MDNS.addService("mqtt", "tcp", MQTT_PORT);
} else
Serial.println("Error setting up mDNS responder!");
/* -----------------------
start HTTPS server |
----------------------- */
server.getServer().setRSACert(new X509List(deviceCert), new PrivateKey(deviceKey));
server.on("/", handleRoot); // standard HTML root
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTPS server started.");
Serial.println();
/* -----------------------
start timer |
----------------------- */
timer.init();
timer.addTask(t1);
// line 177:
timer.enableAll();
}
void loop() {
MDNS.update();
// line 184:
server.handleClient();
mqttClient.loop();
timer.execute();
}
Running MQTT only works fine and publishes data (I use the mosquitto broker).
Running the Web server (https://...) works fine as well, if commenting out line 177 (so MQTT does not get triggered).
With both functions active, as soon as the first MQTT message had been sent, the web server does not answer any more. I get PR_END_OF_FILE_ERROR in FF and ERR_CONNECTION_CLOSED in Chrome.
I guess, that these libraries somehow mess with each other, or that something confuses with the certificates. However, the fingerprint belongs to the server running mosquitto, while the X509 certificate belongs to the web server running on the ESP8266. These are two different machines and have nothing to do with each other.
Any idea welcome.
I suspect both libraries use port 443, and you can only have one listener on a given port. I've tried creating a BearSSL::ESP8266WebServerSecure object with alternate ports, such as 80 and 8443 but can't get them to work. Worse, there doesn't seem to be a way to stop a listener once a BearSSL::ESP8266WebServerSecure object has started, so it can't be released for later reuse.
I ended up using HTTP to get WiFi credentials, then HTTPS from there on out. Not a very satisfactory solution but it works.
Update: I was able to run a provisioning server on port 443, stop it by calling
BearSSL::ESP8266WebServerSecure provisioningServer(443);
BearSSL::ESP8266WebServerSecure server(443);
provisioningServer.close();
provisioningServer.~ESP8266WebServerSecure(); // note: cannot use TLS on both servers without this line
After calling the provisioning server's destructor I was able to start my server on port 443.

How do I catch the COMException thrown by disconnected StreamSocket in C++/CX?

I'm writing an application that should retranslate some data received from Bluetooth LE device to all TCP clients connected to it. The platform is Windows 10. For now it is console application with C++/CX enable as Bluetooth LE API is only available from WinRT. The BLE part is ready but I cannot make proper TCP server using WinRT.
I'm creating TCP socket server using StreamSocketListener and store all StreamSocket objects in std::vector. In a loop iterate the vector and send the data to all connected clients. Everything is working fine at this point. But should one client disconnect and the server crashes as it tries to send a data to disconnected socket and throws COMException and I cannot catch it.
Visual Studio 2015 crash message: Exception thrown at 0x752ADAE8 in SensoCLI.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x02EFE1C0. Call stack points to auto sent = writeTask.get();
Below is the minimal listing of my app that corresponds to the problem:
#include "pch.h"
#using <platform.winmd>
#using <Windows.winmd>
using namespace std;
using namespace Windows::Foundation;
using namespace Platform;
using namespace concurrency;
namespace WFC = Windows::Foundation::Collections;
namespace WNS = Windows::Networking::Sockets;
namespace WSS = Windows::Storage::Streams;
bool shouldStop = false;
// TCP socket server
WNS::StreamSocketListener ^tcpListener;
vector<WNS::StreamSocket ^> *tcpClients;
void OnSocketConnectionReceived(WNS::StreamSocketListener ^aListener, WNS::StreamSocketListenerConnectionReceivedEventArgs ^args);
int main(Array<String ^> ^args)
{
tcpClients = new vector<WNS::StreamSocket ^>();
tcpListener = ref new WNS::StreamSocketListener();
tcpListener->ConnectionReceived += ref new TypedEventHandler<WNS::StreamSocketListener ^, WNS::StreamSocketListenerConnectionReceivedEventArgs ^>(&OnSocketConnectionReceived);
auto listenTask = create_task(tcpListener->BindServiceNameAsync("53450"));
listenTask.wait();
while (!shouldStop)
{
if (tcpClients->size() > 0)
{
auto netDataStream = ref new WSS::InMemoryRandomAccessStream();
auto writer = ref new WSS::DataWriter(netDataStream);
auto reader = ref new WSS::DataReader(netDataStream->GetInputStreamAt(0));
String^ stringToSend("Hello");
writer->WriteUInt32(writer->MeasureString(stringToSend));
writer->WriteString(stringToSend);
auto aTask = create_task(writer->StoreAsync());
unsigned int bytesStored = aTask.get();
aTask = create_task(reader->LoadAsync(bytesStored));
aTask.wait();
auto netData = reader->ReadBuffer(bytesStored);
for (auto iter = tcpClients->begin(); iter != tcpClients->end(); ++iter)
{
create_task((*iter)->OutputStream->WriteAsync(netData)).then([](task<unsigned int> writeTask) {
try
{
// Try getting an exception.
auto sent = writeTask.get();
wcout << L"Sent: " << sent << endl;
}
catch (Exception^ exception)
{
wcout << L"Send failed with error: " << exception->Message->Data() << " " << endl;
}
});
}
Sleep(1000);
}
}
}
void OnSocketConnectionReceived(WNS::StreamSocketListener ^aListener, WNS::StreamSocketListenerConnectionReceivedEventArgs ^args)
{
auto sock = args->Socket;
tcpClients->push_back(sock);
}
How do I properly catch the exception and handle disconnected StreamSocket?

how to connect client immediately one after the other in tcp socket api program

server.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<poll.h>
#include<unistd.h>
#include<arpa/inet.h>
int main()
{
struct pollfd fdarray[5];
int sfd,port,nsfd,n,clen,ret,i;
char str[100];
struct sockaddr_in sadd,cadd;
memset(str,0,sizeof(str));
sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd<0)
{
printf("sorry unable to open the file");
exit(1);
}
memset(&sadd,0,sizeof(sadd));
sadd.sin_port=htons(9796);
sadd.sin_family=AF_INET;
sadd.sin_addr.s_addr=INADDR_ANY;
if(bind(sfd,(struct sockaddr*) &sadd,sizeof(sadd))<0)
{
printf("earror");
exit(0);
}
listen(sfd,5);
clen=sizeof(cadd);
for(i=0;i<5;i++)
{
nsfd=accept(sfd,(struct sockaddr*)&cadd,&clen);
if(nsfd<0)
{
printf("error accepting client");
exit(1);
}
fdarray[i].fd=nsfd;
fdarray[i].events=POLLIN;
fdarray[i].revents=0;
}
while(1)
{
ret=poll(fdarray,5,-1);
for(i=0;i<5;i++)
{
if(fdarray[i].revents==POLLIN)
{
n=read(fdarray[i].fd,str,100);
if(n<0)
printf("arreo");
printf("message is:%s \n",str);
char *buff="message received";
int j;
for( j=0;j<5;j++)
{
if(j!=i)
n=write(fdarray[j].fd,buff,sizeof(buff));
}
}
}
}
return 0;
}
i wrote a program for chat server i.e for example if four client are connected if one of the client send a message then all the other clients should get the message except the sending this process should be done by server i.e client should send to server and server should to all the others now in my code the server waits until all the five clients gets connected what should i do inorder to connect all the clients immediately one after the other not waiting till all are connected
client.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<poll.h>
#include<unistd.h>
int main(int argc,char* argv[])
{
int sfd,i;
char msg[1024];
char blanmsg[1024];
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
sfd=socket(AF_INET,SOCK_STREAM,0);
saddr.sin_family=AF_INET;
inet_pton(AF_INET,"127,0.0.1",&saddr.sin_addr);
saddr.sin_port=htons(9796);
connect(sfd,(struct sockaddr*)&saddr,sizeof(saddr));
for(i=0;i<5;i++)
{
fgets(msg,1024,stdin);
send(sfd,msg,strlen(msg),0);
recv(sfd,blanmsg,sizeof(blanmsg),0);
printf("%s",blanmsg);
fflush(stdout);
}
exit(0);
}
If I understand the question correctly: You want to serve already connected clients while some clients are not yet connected.
You can do that by moving client accept()ing into the while(1) loop.
To do that, you must add the server socket to fdarray, and add client sockets to the fdarray when new clients are accepted.
Here is quite similar example: Single thread echo server implemented by using poll()

connect and send on the socket succeeds, even if WIFI not enabled and server is only reacheable in the wireless network - Windows Mobile 6.5 - C/C++

I wrote a small C/C++ Windows Mobile 6.5 client-application that is connecting to a server and sends some data to this server. The server is in my internal wireless network and is not reacheable outside.
The weird behaviour I'm having:
1) Even if the WIFI is not started on my mobile device, the connect() from the client-application returns success (!= SOCKET_ERROR), which is not the case b/c the server is reacheable only in the wireless network.
2) If the WIFI is not started on my mobile device, if there is a Sleep(1000) between the connect() and the send(), the send() fails with WSAECONNRESET, BUT if there is no Sleep() between the connect() and send() the send() succeeds! (only when doing the read() I finally get the WSAECONNRESET error).
Can somebody pls point me some tips why do I have this behaviour. It's pretty scary that without actually being able to reach the server I still get success for the connect() and for the send() :(
As requested, here is a sample code:
#include <windows.h>
#include <Winsock2.h>
#include "dbgview.h"
# define FxMemZero(buf,len) RtlZeroMemory ((VOID*)(buf),(SIZE_T)(len))
# define FxMemCopy(dst,src,len) RtlCopyMemory ((VOID*)(dst),(CONST VOID*)(src),(SIZE_T)(len))
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
SOCKET proxy_connection;
WSADATA wsadata;
if( 0 != WSAStartup (MAKEWORD(1, 1), &wsadata))
return -1;
proxy_connection = WSASocket (AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
if(proxy_connection == INVALID_SOCKET) {
// error creating the socket
DbgViewTraceError((L"main", L"error creating socket."));
return -1;
}
// try to connect
UINT proxy_ip_ = 0x00000000;
CHAR* proxy_0_ = "192.168.1.105";
UINT proxy_port = 3100;
// get the proxy ip
{
struct hostent *he_;
if((he_ = gethostbyname(proxy_0_)) == NULL) {
DbgViewTraceWarning((L"main", L"error %d resolving hostname %hs", WSAGetLastError(), proxy_0_));
return -1;
}
FxMemCopy((PBYTE)&proxy_ip_, (PBYTE)he_->h_addr, he_->h_length);
}
// prepare the connection data
sockaddr_in saddr_;
FxMemZero(&saddr_,sizeof(sockaddr_in));
saddr_.sin_family = AF_INET;
saddr_.sin_addr.S_un.S_addr = proxy_ip_;// address
saddr_.sin_port = htons((USHORT)proxy_port);
// do the conection
if(SOCKET_ERROR == connect(proxy_connection, (SOCKADDR*) &saddr_, sizeof(saddr_))) {
// error connecting to the proxy
DbgViewTraceWarning(( L"main", L"error %d connecting to %hs:%d", WSAGetLastError(), proxy_0_, proxy_port));
closesocket(proxy_connection);
proxy_connection = INVALID_SOCKET;
return -1;
}
DbgViewTraceInfo(( L"main", L"SUCCESS. connected to %hs:%d.", proxy_0_, proxy_port));
CHAR* buffer_ = "Momo";
UINT count_ = strlen(buffer_);
DWORD total_ = 0;
DWORD sent_ = 0;
while(total_ < count_) {
// ISSUE: IF the WIFI is not started on the mobile, the connect returns success AND the send() returns success, even though with putty
// on the mobile, a telnet on 192.168.1.105:3100 will fail with: "Network error: Connection reset by peer"
// IF I add a long-enough Sleep() between the connect() and the send(), the send() will fail with: WSAECONNRESET
//Sleep(5000);
if(SOCKET_ERROR == (sent_ = send(proxy_connection, (const char*)buffer_ + total_, count_ - total_, 0))) {
// error sending data to the socket
DbgViewTraceError((L"main", L"error %d sending data to proxy", WSAGetLastError()));
return -1;
}
total_ += sent_;
}
DbgViewTraceInfo((L"main", L"send() SUCCESS"));
return 0;
}
The results are:
1) Without Sleep():
main [INFO ] SUCCESS. connected to 192.168.1.105:3100.
main [INFO ] send() SUCCESS
2) With Sleep():
main [INFO ] SUCCESS. connected to 192.168.1.105:3100.
main [ERROR ] error 10054 sending data to proxy
So the questions are:
1) Why the connect() succeeds? How can I be sure that there is actually a real connection?
2) Why the send() succeeds?
3) Why with a Sleep() in between connect() and send() the behaviour is different?
The problem seems to be ActiveSync. If ActiveSync is running, I get the behavior described above (connect() and send() report success, even though they are not). If ActiveSync is not running, gethostbyname() fails with:
WSAENETDOWN -> if WIFI is disabled
WSAHOST_NOT_FOUND -> if WIFI is enabled
which is correct!
How can this be? What is ActiveSync doing that is ruining everything? How can I avoid this problem? I mean, I can't be sure that the user is running my application when there is no ActiveSync running, so what can I do to avoid this behavior when ActiveSync is running?
Thx,
MeCoco
Looks like you are at least misusing struct sockaddr_in. Try more modern API for address conversion - Windows has InetPton - and see if that fixes the issues.