Socket Server
Posted: Tue Apr 11, 2017 8:37 pm
I am trying to create a socket with a client that I can leave open indefinitely where both the server and client can send messages at anytime without have to reopen the socket. The server on the ESP32 can receive one message before being unable to receive any more messages without closing and reopening the client socket.
After enabling some of the debugging options in lwipopts.h, I see that the first time its called there is a buffer where the received message is stored, but after recv is called the netbuff is deleted.
Prior to reading I get the following when I call recv()
After the read I get:
The following code is an an event if that matters. Thanks for any help.
After enabling some of the debugging options in lwipopts.h, I see that the first time its called there is a buffer where the received message is stored, but after recv is called the netbuff is deleted.
Prior to reading I get the following when I call recv()
Code: Select all
lwip_recvfrom: netconn_recv err=0, netbuf=0x3ffc8f40
lwip_recvfrom: buflen=1 len=1024 off=0 sock->lastoffset=0
Code: Select all
lwip_recvfrom: netconn_recv err=-13, netbuf=0x0
lwip_recvfrom(1): buf == NULL, error is "Connection aborted."!
Code: Select all
void socket_main(void *pvParameter)
{
// Create the actual socket
int mainSocket = socket_create(SOCKET_PORT);
if (mainSocket >= 0) {
int option = true;
if (setsockopt(mainSocket, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option)) < 0) {
ESP_LOGE(LOG_TAG, "Failed to keep alive. %s", strerror(errno));
}
// As long as a valid client socket is available keep reading
for (;;) {
int clientSocket = socket_wait_for_client(mainSocket);
if (clientSocket < 0) {
break;
}
while(socket_connection_handler(clientSocket)){}
closesocket(clientSocket);
}
closesocket(mainSocket);
}
vTaskDelete(NULL);
}
Code: Select all
int socket_create(uint16_t portNumber)
{
struct sockaddr_in serverAddress;
// Create the socket
int theSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (theSocket < 0) {
ESP_LOGE(LOG_TAG, "Failed to create socket. Error: %s", strerror(errno));
return theSocket;
}
// Bind the socket to the port
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(portNumber);
int result = bind(theSocket,
(struct sockaddr *) &serverAddress,
sizeof(serverAddress));
if (result < 0) {
ESP_LOGE(LOG_TAG, "Failed to bind socket. Error: %s", strerror(errno));
closesocket(theSocket);
return result;
}
// Indicate that the socket is look for new connections
result = listen(theSocket, SOCKET_BACKLOG);
if (result < 0) {
ESP_LOGE(LOG_TAG, "Failed to listen on socket. Error: %s", strerror(errno));
closesocket(theSocket);
return result;
}
return theSocket;
}
Code: Select all
int socket_wait_for_client(int hostSocket)
{
struct sockaddr_in clientAddress;
socklen_t clientAddrLen = sizeof(clientAddress);
int clientSocket = accept(hostSocket, (struct sockaddr *) &clientAddress, &clientAddrLen);
if (clientSocket < 0) {
ESP_LOGE(LOG_TAG, "Failed to connect to client. Error: %s",strerror(errno));
return clientSocket;
}
return clientSocket;
}
bool socket_connection_handler(int clientSocket)
{
int maxRead = 1024;
char *readData = malloc(maxRead);
bool retVal = false;
ssize_t bytesJustRead;
for (;;) {
// Wait while nothing has been received
do {
// Send whatever is in the outbound, UART to WiFi buffer
check_and_process_out_queue(clientSocket);
// Peek to see what's in the RX buffer
bytesJustRead = recv(clientSocket, readData, maxRead,MSG_PEEK);
// Only delay on an empty RX buffer
if (bytesJustRead == 0) {
vTaskDelay(25 / portTICK_PERIOD_MS);
}
} while (bytesJustRead == 0);
// Actually read this time. If a negative result occurs,
// it will be handled here
bytesJustRead = recv(clientSocket, readData, maxRead, MSG_DONTWAIT);
// Handle errors
if (bytesJustRead < 0) {
ESP_LOGE(LOG_TAG, "Read failed (%i). %s", bytesJustRead, strerror(errno));
} else if (bytesJustRead > 0) {
// Log the read data.
ESP_LOGI(LOG_TAG, "Data read (%i): %.*s", bytesJustRead, bytesJustRead, readData);
retVal = true;
}
}
free(readData);
return retVal;
}