I have a client that looks like this:
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = inet_addr(host_ip);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
int sock = socket(addr_family, SOCK_STREAM, ip_protocol);
/*
connect() handle block
connect successfully
*/
int state = AWAKE;
while(1){
if(state == AWAKE){
int err_socket = sendto(sock, message, strlen(message), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
}
int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
if(len<0){
ESP_LOGE(TCP_TAG, "Error occurred during recving: errno %d", errno); --> error 11
continue;
}
if(strcmp(rx_buffer, "ON") == 0){
state == AWAKE;
}else if(strcmp(rx_buffer, "OFF") == 0){
state == SLEEPING;
}
}
After receiving the "OFF" message, the state will switch to SLEEPING and stop sending messages to the server, but keep receiving messages.
However, when I switch the state to SLEEPING, the recv result will always return -1 while the server keeps sending messages to the client.
My questions is, do it always need send() and recv() as a peer?
No, actually it doesn't, because you are mistakenly using the
==comparison operation where you should be using the=assignment operator. So, yourstatedoesn't actually change value.Even if that were not the case, your
rx_bufferis not null-terminated, so yourstrcmp()calls won't work correctly.That means
recv()is failing. You need to then look aterrnoto find out why. Which, according to your comments, is 11 (EAGAIN), which simply means that the socket is operating in non-blocking mode and there is nothing available to read from the socket at that exact moment, so just try again later. This is not a fatal error.However, an error condition that you are not handling at all is when
recv()returns 0 on peer disconnect. You need to stop your loop in that situation and close your socket.No. TCP is birectional. You can treat the socket as send-only or recv-only, if that is what your protocol requires. Though, do make sure you read from the socket periodically in order to catch peer disconnects and network failures.