netutils/netcat: implemented NETUTILS_NETCAT_SENDFILE option.

This option enables using sendfile() in netcat client mode
if a normal file (not stdin) is sent. If the option is enabled
but stdin is sent rather than a normal file, netcat falls back
to the combination of read() and write().
Using sendfile() provides a higher performance compared to
the combination of read() and write().

Also this option is useful for testing / debugging tcp_sendfile()
functionality of NuttX TCP/IP stack.
This commit is contained in:
Alexander Lunev 2022-01-04 09:29:05 +03:00 committed by Xiang Xiao
parent df53de1d68
commit b9a6dc2a85
2 changed files with 57 additions and 1 deletions

View File

@ -47,4 +47,16 @@ config NETUTILS_NETCAT_STACKSIZE
int "netcat stack size" int "netcat stack size"
default DEFAULT_TASK_STACKSIZE default DEFAULT_TASK_STACKSIZE
config NETUTILS_NETCAT_SENDFILE
bool "Use sendfile() in netcat when possible"
default y
depends on NET_SENDFILE
---help---
This option enables using sendfile() in netcat client mode
if a normal file (not stdin) is sent. If the option is enabled
but stdin is sent rather than a normal file, netcat falls back
to the combination of read() and write().
Using sendfile() provides a higher performance compared to
the combination of read() and write().
endif endif

View File

@ -31,7 +31,9 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <sys/sendfile.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h>
#include <arpa/inet.h> #include <arpa/inet.h>
/**************************************************************************** /****************************************************************************
@ -166,6 +168,11 @@ int netcat_client(int argc, char * argv[])
char *host = "127.0.0.1"; char *host = "127.0.0.1";
int port = NETCAT_PORT; int port = NETCAT_PORT;
int result = EXIT_SUCCESS; int result = EXIT_SUCCESS;
#ifdef CONFIG_NETUTILS_NETCAT_SENDFILE
struct stat stat_buf;
off_t offset;
ssize_t len;
#endif
if (argc > 1) if (argc > 1)
{ {
@ -187,6 +194,16 @@ int netcat_client(int argc, char * argv[])
result = 1; result = 1;
goto out; goto out;
} }
#ifdef CONFIG_NETUTILS_NETCAT_SENDFILE
if (fstat(infd, &stat_buf) == -1)
{
perror("fstat");
infd = STDIN_FILENO;
result = 1;
goto out;
}
#endif
} }
id = socket(AF_INET , SOCK_STREAM , 0); id = socket(AF_INET , SOCK_STREAM , 0);
@ -214,7 +231,34 @@ int netcat_client(int argc, char * argv[])
goto out; goto out;
} }
result = do_io(infd, id); #ifdef CONFIG_NETUTILS_NETCAT_SENDFILE
if (argc > 3)
{
len = stat_buf.st_size;
offset = 0;
while (len > 0)
{
result = sendfile(id, infd, &offset, len);
if (result == -1 && errno == EAGAIN)
{
continue;
}
else if (result == -1)
{
perror("sendfile error");
break;
}
len -= result;
}
}
else
#endif
{
result = do_io(infd, id);
}
out: out:
if (id != -1) if (id != -1)