summaryrefslogtreecommitdiffstats
path: root/test/test-writev.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/test-writev.c')
-rw-r--r--test/test-writev.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/test/test-writev.c b/test/test-writev.c
new file mode 100644
index 0000000..83b6503
--- /dev/null
+++ b/test/test-writev.c
@@ -0,0 +1,101 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ test-writev: use this to figure out if your writev() does intelligent
+ things on the network. Some writev()s when given multiple buffers
+ will break them up into multiple packets, which is a waste.
+
+ Linux prior to 2.0.31 has this problem.
+
+ Solaris 2.5, 2.5.1 doesn't appear to, 2.6 hasn't been tested.
+
+ IRIX 5.3 doesn't have this problem.
+
+ To use this you want to snoop the wire with tcpdump, and then run
+ "test-writev a.b.c.d port#" ... against some TCP service on another
+ box. For example you can run it against port 80 on another server.
+ You want to look to see how many data packets are sent, you're hoping
+ only one of size 300 is sent.
+*/
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+#ifndef INADDR_NONE
+#define INADDR_NONE (-1ul)
+#endif
+
+void main( int argc, char **argv )
+{
+ struct sockaddr_in server_addr;
+ int s;
+ struct iovec vector[3];
+ char buf[100];
+ int i;
+ const int just_say_no = 1;
+
+ if( argc != 3 ) {
+usage:
+ fprintf( stderr, "usage: test-writev a.b.c.d port#\n" );
+ exit( 1 );
+ }
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_addr.s_addr = inet_addr( argv[1] );
+ if( server_addr.sin_addr.s_addr == INADDR_NONE ) {
+ fprintf( stderr, "bogus address\n" );
+ goto usage;
+ }
+ server_addr.sin_port = htons( atoi( argv[2] ) );
+
+ s = socket( AF_INET, SOCK_STREAM, 0 );
+ if( s < 0 ) {
+ perror("socket");
+ exit(1);
+ }
+ if( connect( s, (struct sockaddr *)&server_addr, sizeof( server_addr ) )
+ != 0 ) {
+ perror("connect");
+ exit(1);
+ }
+
+ if( setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&just_say_no,
+ sizeof(just_say_no)) != 0 ) {
+ perror( "TCP_NODELAY" );
+ exit(1);
+ }
+ /* now build up a two part writev and write it out */
+ for( i = 0; i < sizeof( buf ); ++i ) {
+ buf[i] = 'x';
+ }
+ vector[0].iov_base = buf;
+ vector[0].iov_len = sizeof(buf);
+ vector[1].iov_base = buf;
+ vector[1].iov_len = sizeof(buf);
+ vector[2].iov_base = buf;
+ vector[2].iov_len = sizeof(buf);
+
+ i = writev( s, &vector[0], 3 );
+ fprintf( stdout, "i=%d, errno=%d\n", i, errno );
+ exit(0);
+}