Blocking TCP Connetion reads, but sends empty messages

rolobr
Posts: 7
Joined: Thu Feb 15, 2018 3:49 pm

Blocking TCP Connetion reads, but sends empty messages

Postby rolobr » Mon May 07, 2018 2:53 pm

Hello,
I would like to use a blocking tcp socket to first receive messages an then send a message after I got a message.
The blocking receiver works fine but the sender is only sending two empty tcp messages.
If I set "fcntl(cs,F_SETFL,O_NONBLOCK);" instead of "fcntl(cs,F_SETFL,0);" receiving and sending works fine but is not blocking anymore like I would like to have it.

It would be really nice if you could help me.

In the following you find my tcp socket code.

Thank you very much in advance :-)

Code: Select all

void tcp_server(void *pvParam){
	static char messageReceived[100];
	bool messageReceivedIni = false;
    ESP_LOGI(tag,"tcp_server task started \n");
    struct sockaddr_in tcpServerAddr;
    tcpServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    tcpServerAddr.sin_family = AF_INET;
    tcpServerAddr.sin_port = htons( UNICAST_PORT );
    int s, r;
    char recv_buf[64];
    static struct sockaddr_in remote_addr;
    static unsigned int socklen;
    socklen = sizeof(remote_addr);
    int cs;//client socket
    xEventGroupWaitBits(wifi_event_group,CONNECTED_BIT,false,true,portMAX_DELAY);
    while(1){
        s = socket(AF_INET, SOCK_STREAM, 0);
        if(s < 0) {
            ESP_LOGE(tag, "... Failed to allocate socket.\n");
            vTaskDelay(1000 / portTICK_PERIOD_MS);
            continue;
        }
        ESP_LOGI(tag, "... allocated socket\n");
         if(bind(s, (struct sockaddr *)&tcpServerAddr, sizeof(tcpServerAddr)) != 0) {
            ESP_LOGE(tag, "... socket bind failed errno=%d \n", errno);
            close(s);
            vTaskDelay(4000 / portTICK_PERIOD_MS);
            continue;
        }
        ESP_LOGI(tag, "... socket bind done \n");
        if(listen (s, 2) != 0) { //Number of pending connections
            ESP_LOGE(tag, "... socket listen failed errno=%d \n", errno);
            close(s);
            vTaskDelay(4000 / portTICK_PERIOD_MS);
            continue;
        }
        while(1){
            cs=accept(s,(struct sockaddr *)&remote_addr, &socklen);
            ESP_LOGI(tag,"New connection request,Request data:");
          
            //fcntl(cs,F_SETFL,O_NONBLOCK);
            fcntl(cs,F_SETFL,0);

            bzero(recv_buf, sizeof(recv_buf)); 
            r = recv(cs, recv_buf, sizeof(recv_buf)-1,0);
            while(r > 0)
            {
            	if(messageReceivedIni == false)
            	{
            		strncpy(messageReceived, recv_buf,r);
            		messageReceivedIni = true;
            	}
            	else
            	{
            		strncat(messageReceived, recv_buf,r);
            	}

            	printf("Mess: %s Buf: %s", messageReceived, recv_buf);
               	bzero(recv_buf, sizeof(recv_buf)); 
            	r = recv(cs, recv_buf, sizeof(recv_buf)-1,0); 
            }


            ESP_LOGI(tag, "... done reading from socket. Last read return=%d errno=%d\r\n", r, errno); //Always returns r=0, errno=128. 128 is not written in the lwip documentation.

            char message[100] = "abcdweffaaerfawefwefwefawf";
            if( write(cs , message , strlen(message)) < 0) //Is evaluated as false, but only two empty tcp messages are sent to the receiver!
            {
                ESP_LOGE(tag, "... Send failed \n");
                close(s);
                vTaskDelay(4000 / portTICK_PERIOD_MS);
                continue;
            }
            ESP_LOGI(tag, "... socket send success");  //Is written out
            close(cs);
        }
        ESP_LOGI(tag, "... server will be opened in 5 seconds");
        vTaskDelay(5000 / portTICK_PERIOD_MS);
    }
    ESP_LOGI(tag, "...tcp_client task closed\n");
}

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: Blocking TCP Connetion reads, but sends empty messages

Postby fly135 » Mon May 07, 2018 5:52 pm

Not sure exactly what you are asking, but sounds like you need a timeout.

Code: Select all

if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
                sizeof(timeout)) < 0)
        error("setsockopt failed\n");

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Blocking TCP Connetion reads, but sends empty messages

Postby kolban » Mon May 07, 2018 6:08 pm

Just a wild guess ... but in your code, perhaps change your call to "write()" to a call to "send()". While I fully understand your use of "write" which is great on Unix, I question if "write" is correct on ESP32? We know that "send()" works ... maybe test with that?
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: Blocking TCP Connetion reads, but sends empty messages

Postby fly135 » Mon May 07, 2018 6:29 pm

Also if your write fails you close the listening socket, which makes no sense in the context of your code.

John

Who is online

Users browsing this forum: alanesq, Baidu [Spider], ESP_Roland, geoffw123 and 61 guests