You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/01/05 05:29:07 UTC

[incubator-nuttx-apps] branch master updated: 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().

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new b9a6dc2  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().
b9a6dc2 is described below

commit b9a6dc2a856f02db18f7e73bb8dffe54800f0676
Author: Alexander Lunev <al...@mail.ru>
AuthorDate: Tue Jan 4 09:29:05 2022 +0300

    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.
---
 netutils/netcat/Kconfig       | 12 +++++++++++
 netutils/netcat/netcat_main.c | 46 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/netutils/netcat/Kconfig b/netutils/netcat/Kconfig
index 4317069..d24e033 100644
--- a/netutils/netcat/Kconfig
+++ b/netutils/netcat/Kconfig
@@ -47,4 +47,16 @@ config NETUTILS_NETCAT_STACKSIZE
 	int "netcat stack size"
 	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
diff --git a/netutils/netcat/netcat_main.c b/netutils/netcat/netcat_main.c
index 95c20e2..a345afa 100644
--- a/netutils/netcat/netcat_main.c
+++ b/netutils/netcat/netcat_main.c
@@ -31,7 +31,9 @@
 #include <unistd.h>
 #include <string.h>
 
+#include <sys/sendfile.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <arpa/inet.h>
 
 /****************************************************************************
@@ -166,6 +168,11 @@ int netcat_client(int argc, char * argv[])
   char *host = "127.0.0.1";
   int port = NETCAT_PORT;
   int result = EXIT_SUCCESS;
+#ifdef CONFIG_NETUTILS_NETCAT_SENDFILE
+  struct stat stat_buf;
+  off_t offset;
+  ssize_t len;
+#endif
 
   if (argc > 1)
     {
@@ -187,6 +194,16 @@ int netcat_client(int argc, char * argv[])
           result = 1;
           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);
@@ -214,7 +231,34 @@ int netcat_client(int argc, char * argv[])
       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:
   if (id != -1)