Stream Read Error: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host - windows-services

I am working on a windows service to communicate with servers, In which I am using the TcpListener class.
In TcpListener class, after 3 successful socket connections, the 4th connection is returning an error.
class MyTcpListener
{
public static void Main()
{
TcpListener server=null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
while(true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also use server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while((i = stream.Read(bytes, 0, bytes.Length))!=0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
// Process the data sent by the client.
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", data);
}
// 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();
}
}
On this line on the 4th connection, it's returning an error.
// Send back a response.
stream.Write(msg, 0, msg.Length);
Error:
Stream Write Error: Unable to write data to the transport connection:
An existing connection was forcibly closed by the remote host. Stream
Write Error: at System.Net.Sockets.NetworkStream.Write(Byte[]
buffer, Int32 offset, Int32 size)

Related

Exception decoder after connected with PubSubClient in my ESP8266

My code always gets exception decoder message and resets a few ms after MQTT connection is done successfully.
My connectMqtt function:
void MyClass::connectMqtt(PubSubClient client)
{
// Loop until we're reconnected
int attempts = 0;
bool connected = false;
while (!connected && attempts < 5)
{
std::string clientId = _my_device.getBarcode();
// Attempt to connect
if (client.connect(clientId.c_str(), _my_device.getMqttUser(), _my_device.getMqttPassword()))
{
Serial.println(F("MQTT connected"));
connected = true;
//Subscribe to config topic of the device
//TODO not done yet
}
else
{
Serial.print(F("failed, rc="));
Serial.print(client.state());
Serial.println(F(" try again in 5 seconds"));
attempts++;
// Wait 5 seconds before retrying
delay(5000);
}
}
Serial.println(F("Done."));
}
Exception decoder mesage starts by:
Exception (3):
epc1=0x40100691 epc2=0x00000000 epc3=0x00000000 excvaddr=0x40032468 depc=0x00000000
As #Juraj said:
The solution is passing a reference to the function, not a copy
void MyClass::connectMqtt(PubSubClient& client)

How do I initialize LwIP to use MQTT library

I've looked and followed documentation from LwIP 2.0.2. My project contains the MQTT library supplied in the LwIP 2.0.2. I also found some help at https://dzone.com/articles/mqtt-with-lwip-and-the-nxp-frdm-k64f. I'm unable to get a connection, I've used free public MQTT broker but no hope in connection. I can ping my device. Am I doing something wrong?
static void mqtt_test(mqtt_client_t *mqtt_client)
if (mqtt_client_is_connected(&mqtt_client) == 1)
{
example_subscribe(&mqtt_client, NULL);
} else {
mqtt_do_connect(&mqtt_client);
}
}
when I call this method it always enters mqtt_do_connect() never connecting. Here is mqtt_do_connect
static void mqtt_do_connect(mqtt_client_t *mqtt_client)
{
ip4_addr_t broker_ipaddr;
struct mqtt_connect_client_info_t ci;
err_t err;
if (ipaddr_aton("52.58.177.181", &broker_ipaddr))
{
err = ERR_OK;
}
/* Setup an empty client info structure */
memset( & ci, 0, sizeof(ci));
/* Minimal amount of information required is client identifier, so set it here */
ci.client_id = "test";
/* Initiate client and connect to server, if this fails immediately an error code is returned
otherwise mqtt_connection_cb will be called with connection result after attempting
to establish a connection with the server.
For now MQTT version 3.1.1 is always used */
err = mqtt_client_connect(mqtt_client, & broker_ipaddr, 1883, mqtt_connection_cb, 0, & ci);
/* For now just print the result code if something goes wrong */
if (err != ERR_OK) {
printf("mqtt_connect return %d\n", err);
}
}
I've also noticed in the method mqtt_client_connect in mqtt.c that this exists:
/* Any local address, pick random local port number */
err = tcp_bind(client->conn, IP_ADDR_ANY, 0);
why is this needed? If I replace IP_ADDR_ANY to my local address of the static IP of the device it runs through without throwing a error but no callback mqtt_connection_cb is then called.
I've also initialized the TCP/IP stack as mentioned with static IP. I'm using NO_SYS as 1 but will move it over to FreeRTOS but baby steps first.
I haven't found much support on MQTT in LwIP implementation, am I missing something obvious, any help will be appreciated.
I've used MQTTfx to run a test or two on the broker with good response but nothing from my embedded device (Atmel SAME54).
I've found the solution. I ran my TCP setup in a FreeRTOS thread and opened a socket
static void mqtt_start(void *p)
{
struct sockaddr_in address;
int s_create, new_socket;
int addrlen = sizeof(address);
int opt = 1;
int socket_check;
sys_sem_t sem;
err_t err_sem;
err_sem = sys_sem_new(&sem, 0); /* Create a new semaphore. */
tcpip_init(tcpip_init_done, &sem);
sys_sem_wait(&sem); /* Block until the lwIP stack is initialized. */
sys_sem_free(&sem); /* Free the semaphore. */
/*Create a socket*/
s_create = socket(AF_INET, 1, 0);
setsockopt(s_create, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(IPADDR_ANY);
address.sin_port = htons(HTTP_PORT);
/* bind the connection to port */
socket_check = bind(s_create, (struct sockaddr *)&address, sizeof(address));
if (socket_check < 0) {
LWIP_DEBUGF(LWIP_DBG_ON, ("Bind error=%d\n", socket_check));
goto socket_close;
}
/* tell the connection to listen for incoming connection requests */
listen(s_create, 3);
mqtt_connect(&mqtt_client);
for (;;) {
new_socket = accept(s_create, (struct sockaddr *)&address, (socklen_t *)&addrlen);
socket_close:
close(new_socket);
}
}
I also had a problem with my initialization of my mqtt client, placed a watch on it and saw the struct wasn't initializing. I initialized it globally
mqtt_client_t mqtt_client;
Then use it later in mqtt_start.

CFSocket data callbacks

In an iPhone app, I create a CFSocket object from an existing native UDP socket and set up a data callback whenever the socket receives some data. I then add that to my main program loop:
//Set socket descriptor field
cbData.s = udpSocket.getSocketDescriptor();
CFSocketContext udpSocketContext;
memset(&udpSocketContext, 0, sizeof(udpSocketContext));
udpSocketContext.info = &cbData;
cbData.socketRef = CFSocketCreateWithNative(NULL, cbData.s, kCFSocketDataCallBack, &getSocketDataCallBack, &udpSocketContext);
cbData.runLoopSourceRef = CFSocketCreateRunLoopSource( NULL, cbData.socketRef, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), cbData.runLoopSourceRef, kCFRunLoopCommonModes);
I send 1024-byte datagrams over WiFi from a separate Mac server app every 5 mS, and receive them on my iPhone in my getSocketDataCallBack routine.
I expect getSocketDataCallBack to be called every 5 mS (to match the period of the datagrams being sent from the Mac), which happens the majority of times. BUT, the calls often get delayed by 10s or 100s of mS. Thereafter, I get a rapid sequence of callbacks (fractions of a mS) to retrieve the multiple datagrams that have piled up over that delay.
As iOS obviously keeps the delayed datagrams around,
is there any way to grab all the delayed datagrams from the system at
once instead of getSocketDataCallBack being called over and over
in quick succession?
[I do query how many bytes are available in the callback ala:
CFDataRef dataRef = (CFDataRef)data;
numBytesReceived = CFDataGetLength(dataRef);
but 'numBytesReceived' is always reported as 1024.]
Alternatively, is there any way to improve/lessen the socket callback
timing variability through other means?
I'm using socket call back for Inter Process Communication (actually, inter thread communication) with UNIX socket. How we use socket is identical to the TCP/UDP.
The code below is written in c/obj-c and using posix thread. To translate it to Swift/NSThread should not be difficult.
Note the program below works as a server side, which means the program creates socket where the clients connect to. Once the client connected to the socket, the system automatically accepts the connection and allocates
another file descriptor to read/write. The socket call back reflects this two stage operation. Initially we create the socket, we then add as run-loop source so the system can call the call back when the client attempted to connect. The system accepts, then allocates and tells the call back
a file descriptor to read/write with the client. We then create another run-loop source from the read/write fd and add to run-loop. This second call back is called when rx/tx data is ready.
MAIN THREAD:
The main thread creates UNIX socket and worker thread. The socket fd is passed as argument of the worker thread.
#import <stdio.h>
#import <string.h>
#import <stdlib.h>
#import <unistd.h>
#import <pthread.h>
#import <sys/socket.h>
#import <sys/un.h>
#import <sys/stat.h>
#import <sys/types.h>
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
int setup(const char *ipcNode) {
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
return -1;
}
struct sockaddr_un sa = {0};
sa.sun_len = sizeof(sa);
sa.sun_family = AF_UNIX;
strcpy(sa.sun_path, ipcNode);
remove(sa.sun_path);
if (bind(sockfd, (struct sockaddr*)&sa, sizeof(struct sockaddr_un)) == -1) {
close(sockfd);
return -1;
}
// start up worker thread
pthread_attr_t at;
pthread_attr_init(&at);
pthread_attr_setdetachstate(&at, PTHREAD_CREATE_DETACHED);
pthread_t th;
pthread_create(&th, &at, workerThread, (void *)(long)(sockfd));
return 1;
}
WORKER THREAD:
The program works as a server. So, it waits to get connected by client (via connect()). Once it's connected, the system automatically calls accept() and allocates read/write fd to communicate with the client. This fd is passed to accept-call back routine socketDataCallback(). Then we create another call back clientDataCallback() with the read/write fd.
// worker thread
//
void *workerThread(void *tprm) {
int sockfd = (int)tprm;
int retval = listen(sockfd, 1); // mark as "server" side. here, accept only 1 connection request at a time
if (retval != 0) {
return NULL;
}
// create CFSocket and register it as data source.
CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault, sockfd, kCFSocketAcceptCallBack, socketDataCallback, nil);
// don't close native fd on CFSocketInvalidate
CFSocketSetSocketFlags(socket, CFSocketGetSocketFlags(socket) & ~kCFSocketCloseOnInvalidate);
// create run loop source
CFRunLoopSourceRef socketRunLoop = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
// add to run loop
CFRunLoopAddSource(CFRunLoopGetCurrent(), socketRunLoop, kCFRunLoopCommonModes);
CFRelease(socketRunLoop);
CFRelease(socket);
CFRunLoopRun();
// not return here untill run loop stops
close(sockfd);
return NULL;
}
// socket connection w/ client side. create another data source and add to run-loop
//
void socketDataCallback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info) {
CFSocketContext socketContext;
memset(&socketContext, 0, sizeof(CFSocketContext));
int clientfd = *((int *)data); // get file descriptor (fd)
socketContext.info = (void *)((long)clientfd); // set fd at info of socketContext
// create CFSocket for tx/rx w/ connected client
CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault, clientfd, kCFSocketReadCallBack | kCFSocketWriteCallBack, clientDataCallback, &socketContext);
CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack);
CFRunLoopSourceRef socketRunLoop = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), socketRunLoop, kCFRunLoopCommonModes);
CFRelease(socket);
CFRelease(socketRunLoop);
}
// data to/from client
//
void clientDataCallback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info) {
if (callbackType & kCFSocketWriteCallBack) {
// your own tx data prcess here
// txDataCallback(s, callbackType, address, data, info);
}
if (!(callbackType & kCFSocketReadCallBack)) return;
// extract fd
int fd = (int)((long)info);
// read data, and do some work
uint8_t rxdata[1024];
size_t nr = read(fd, rxdata, 1024);
if (!nr) {
// socket closed
handleSocketClosed(s);
return;
}
// your own rx process here
}
// socket closed
//
void handleSocketClosed(CFSocketRef s) {
// any clean up process here, then
CFSocketInvalidate(s);
// stop run loop if necessary
// CFRunLoopStop(CFRunLoopGetCurrent());
}
If you are working at client side, things get a bit easier. You get a read/write fd with connect() call. Then you create CFSockeRef and add to run-loop by using the fd.
Hope this helps.
EDIT: How to wait with POSIX select(). To wait with POSIX select() at worker thread is simpler than socket call back. If you are on client side, then:
int sockfd = socket(...);
bind(sockfd, ...)
connect(sockfd, ...);
while (1) {
int nfds = sockfd+1;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(sockfd, &rfds);
int retval = select(nfds, &rfds, NULL, NULL, NULL);
if (retval == -1) break;
if (retval > 0) {
uint8_t rxdata[1024];
size_t nr = read(sockfd, rxdata, 1024);
if (!nr) {
// socket closed.
break;
}
// do your rx process here
}
}
Run the code above at your worker thread.

ESP8266 code not working properly

This is ESP8266 code to turn ON/OFF an LED. I'm using the Arduino IDE built-in example code. The LED is working properly but I want to send HTTP requests to my locally-hosted web site (which send emails) but it's not working.
Connected with my local Wifi
Assigned a static IP
When I hit 192.168.1.101/gpio/1(Led ON)
When I hit 192.168.1.101/gpio/0(Led OFF) It's working but unable to hit my web site.
When I hit 192.168.1.101/gpio/1 then it should hit my locally-hosted URL (192.168.1.100/home/ardchk)
Kindly help me to sort out this issue.
#include <ESP8266WiFi.h>
const char* ssid = "SMART";
const char* password = "123456789";
const char* host = "192.168.1.100"; // Your domain
IPAddress ip(192, 168, 1, 101); // where xx is the desired IP Address
IPAddress gateway(192, 168, 1, 1); // set gateway to match your network
IPAddress subnet(255, 255, 255, 0);
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
// prepare GPIO3
pinMode(3, OUTPUT);
digitalWrite(3, 0);
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.config(ip,gateway,subnet);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.println(WiFi.localIP());
}
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()) {
delay(1);
}
// Read the first line of the request
String req = client.readStringUntil('\r');
Serial.println(req);
// Match the request
int val;
if (req.indexOf("/gpio/0") != -1) {
val = 0;
if (client.connect(host, 80)) {
//starts client connection, checks for connection
Serial.println("connected to website/server");
client.println("GET /home/ardchk HTTP/1.1"); //Send data
client.println("Host: 192.168.1.100");
Serial.println("Email Sended");
client.println("Connection: close");
//close 1.1 persistent connection
client.println(); //end of get request
}
} else if (req.indexOf("/gpio/1") != -1) {
val = 1;
} else {
Serial.println("invalid request");
client.stop();
return;
}
// Set GPIO2 according to the request
digitalWrite(3, val);
client.flush();
// Prepare the response
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
s += (val)?"high":"low";
s += "</html>\n";
// Send the response to the client
client.print(s);
delay(1);
Serial.println("Client disconnected");
// The client will actually be disconnected
// when the function returns and 'client' object is destroyed
}
Based on your question/comment, I am assuming that client.connect(host, 80) is returning false.
I believe you are unable to connect to your host because your are trying to connect twice with the same client.
Your code looks like this:
// returns an already connected client, if available
WiFiClient client = server.available()
//...
if (client.connect(host, 80)) {/*...*/}
You see, you are using the already connected client to attempt to connect to your host. Instead, try creating a separate WiFiClient for that job:
WiFiClient requesting_client = server.available();
//...
if (req.indexOf("/gpio/0") != -1) {
val = 0;
// create a fresh, new client
WiFiClient emailing_client;
if (emailing_client.connect(host, 80)) {
// ...
// don't forget that you need to close this client as well!
emailing_client.stop();
}
Hope this helps!

Android to Arduino Uno + Wi-Fi shield string communication

I am trying to make a wireless light control device (on/off/dimming) using an Arduino, an Android app, and a router.
I am setting the Arduino to a static IP 192.168.1.2 using the router. I am sending strings ("1"-off, "2"-decrease brightness, "3"-increase brightness, "4"-on) from the Android app to the IP address 192.168.1.2. I have connected the Arduino to the Internet using the Arduino Wi-Fi shield and set up the WifiServer using the following code:
char ssid[] = "NAME"; // Your network SSID (name)
char pass[] = "PASS"; // Your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // Your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
WiFiServer server(23);
boolean alreadyConnected = false; // Whether or not the client was connected previously.
void setup() {
// Start serial port:
Serial.begin(9600);
// Attempt to connect to Wi-Fi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
// Wait 10 seconds for connection:
delay(10000);
}
// Start the server:
server.begin();
// You're connected now, so print out the status:
printWifiStatus();
}
The main problem I am having is how to accept and print out the strings from the Android device. The current code I have to do this is:
// Listen for incoming clients
WiFiClient client = server.available();
if (client) {
// An HTTP request ends with a blank line
boolean newLine = true;
String line = "";
while (client.connected() && client.available()) {
char c = client.read();
Serial.print(c);
// 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' && newLine) {
// Send a standard HTTP response header
//client.println("HTTP/1.1 200 OK");
//client.println("Content-Type: text/html");
//client.println();
}
if (c == '\n') {
// You're starting a new line
newLine = true;
Serial.println(line);
line = "";
}
else if (c != '\r') {
// You've gotten a character on the current line
newLine = false;
line += c;
}
}
Serial.println(line);
// Give the web browser time to receive the data
delay(1);
// Close the connection:
//client.stop();
}
}
I am basing this code off of the blog post Android Arduino Switch with a TinyWebDB hack, but this code is for an Ethernet shield. The Android app was made using the MIT App Inventor, which is similar to the one found the blog post.
TLDR, how can I get the strings using the Arduino Wi-Fi shield?
You can read the characters into a full string instead of reading each individual character into the serial monitor as in your example above.
In your example, this bit of code would read each character from the client TCP session and print it to the serial monitor, thus displaying the HTTP requests in the serial console.
char c = client.read();
Serial.print(c);
Try something like this instead. Declare a string named "readString" before your setup() function in the Arduino sketch like this:
String readString;
void setup() {
//setup code
}
void loop() {
// Try this when you're reading inside the while client.connected loop instead of the above:
if (readString.length() < 100) {
readString += c;
Serial.print(c);
}
Here is a working example of the loop():
void loop() {
// Listen for incoming clients
WiFiClient 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();
//Serial.write(c);
// 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 (readString.length() < 100) {
readString += c;
Serial.print(c);
}
if (c == '\n' && currentLineIsBlank) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connnection: close");
client.println();
client.println("<!DOCTYPE HTML>");
//send the HTML stuff
client.println("<html><head><title>Admin Web</title><style type=\"text/css\">");
client.println("body { font-family: sans-serif }");
client.println("h1 { font-size: 14pt; }");
client.println("p { font-size: 10pt; }");
client.println("a { color: #2020FF; }");
client.println("</style>");
client.println("</head><body text=\"#A0A0A0\" bgcolor=\"#080808\">");
client.println("<h1>Arduino Control Panel</h1><br/>");
client.println("<form method=\"link\" action=\"/unlockdoor\"><input type=\"submit\" value=\"Unlock Door!\"></form>");
client.println("<br/>");
client.println("</body></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 disonnected");
if (readString.indexOf("/unlockdoor") > 0)
{
unlockdoor();
Serial.println("Unlocked the door!");
}
readString = "";
}

Resources