Reputation: 15171
Is it ever possible for the C send
function to return zero when using TCP sockets? The man page just says that it will return the number of bytes sent, but I am not sure if it will just return -1 when it can't send any data.
Upvotes: 24
Views: 23828
Reputation: 7516
send
returns 0 when you send(socket, buf, 0, 0)
I'd like to provide simple code for others to test.
In one terminal:
nc -l localhost 10086
In another terminal:
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
int create_socket()
{
addrinfo hints = {};
addrinfo* servinfo;
int sockfd = -1;
int rv;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
if ((rv = getaddrinfo("localhost", "10086", &hints, &servinfo)))
{
printf("getaddrinfo failed: %s\n", gai_strerror(rv));
exit(1);
}
for(auto p = servinfo; p; p = p->ai_next)
{
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
{
perror("socket");
continue;
}
else
{
if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1)
{
close(sockfd);
perror("connect");
continue;
}
else
puts("client: connected");
}
break;
}
freeaddrinfo(servinfo);
return sockfd;
}
void client()
{
int socket = create_socket();
if(socket == -1)
{
puts("no good");
exit(1);
}
char buf[100] = {0};
while(1){
int ret = send(socket, buf, 0, 0);
if (ret == 0){
printf(".");
}else{
printf("xxxxxxx\n");
}
}
}
int main()
{
setvbuf(stdout, NULL, _IONBF, 0);
client();
return 0;
}
g++ -g -Wall -o send_zero_bytes send_zero_bytes.cpp
./send_zero_bytes
Upvotes: 3
Reputation: 1037
I do observe a zero return from the send(2)
on an AF_UNIX
type socket right now.
Yepp, it was due to the size
field of zero value.
So, JFYI.
Upvotes: 3
Reputation: 311023
The BSD man page states:
If no messages space is available at the socket to hold the message to be transmitted, then send() normally blocks, unless the socket has been placed in non-blocking I/O mode.
The Posix specification goes further and states that in blocking mode all data is transferred, unless an interrupt occurs.
In both cases zero cannot be returned unless the count supplied was zero.
Upvotes: 4
Reputation: 882326
I'm pretty certain, though the memory is deep in the mists of time, that I've seen it return zero before, in the situation of massive data transfers where the other end was not keeping up.
From memory, in that case, the remote TCP stack buffers had filled up, the stack had notified the local end that it was to delay until some space was cleared out and the local buffers had filled up as well.
At that point, it's not technically an error (hence no -1 returned) but no data could be accepted by the local stack.
I'm not entirely certain that's the case now since the current Posix standard seems to indicate it will simply block in that case (or fail if it's set up for non-blocking).
However, I suspect it's a moot point. You do have the possibility that it will return less than the bytes you requested to send and you therefore should have code in place to handle that.
And, since it will be pretty much the same logic handling 'one less than what you requested' as handling 'zero bytes', you may as well assume it can return zero.
Upvotes: 23
Reputation: 5812
The answer to this may well be implementation dependent and therefore vary based on the operating system.
One circumstance where 0 would be expected, when you request a transmission of 0 bytes.
Upvotes: 5
Reputation: 73279
Well, there is always the case where you passed in zero as the number of bytes to send... in that case, "returning the number of bytes sent" would indicate that it should return zero bytes.
Probably best to handle the returns-zero case properly anyway; it can't hurt, and it might help.
Upvotes: 6