LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 09-20-2010, 12:41 PM   #1
bennymack
LQ Newbie
 
Registered: Sep 2010
Posts: 2

Rep: Reputation: 0
splice() from pipe to TCP buffered?


I wrote a small test program to see if a simple proxy would benefit from using splice() but it always takes 200ms for the data that I spliced from a pipe to a TCP socket to be read from the other end of the socket.

Here is the Perl program to test it:

Code:
package test_pipes_2;
use strict;
use warnings;
use IO::Handle();
use POSIX qw(:errno_h);
use Time::HiRes qw(time);
use English qw(-no_match_vars);
use IO::Socket::INET;
use Socket qw(IPPROTO_TCP TCP_NODELAY);

__PACKAGE__->run if not caller;

sub run {
    my( $class ) = @ARG;

    pipe my $parent_reader, my $child_writer;
    my $parent_reader_fd = fileno $parent_reader;
    my $child_writer_fd  = fileno $child_writer;
    pipe my $child_reader,  my $parent_writer;
    my $child_reader_fd  = fileno $child_reader;
    my $parent_writer_fd = fileno $parent_writer;

    my $server = IO::Socket::INET->new(
        LocalAddr   => '127.0.0.1:9000',
        Type        => SOCK_STREAM,
        Listen      => 5,
        ReuseAddr   => 1,
        Blocking    => 1,
    ) || die $OS_ERROR;

    my $client_browser = IO::Socket::INET->new(
        PeerAddr   => '127.0.0.1:9000',
        Type        => SOCK_STREAM,
        Blocking    => 1,
    ) || die $OS_ERROR;
#   setsockopt $client_browser, IPPROTO_TCP, TCP_NODELAY, 1;
    my $client_browser_fd = fileno $client_browser;

    my $server_browser = $server->accept() || die $OS_ERROR;
#   setsockopt $server_browser, IPPROTO_TCP, TCP_NODELAY, 1;
    my $server_browser_fd = fileno $server_browser;

    for( 1 .. 3 ) { #  100_000
        syswrite $client_browser, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n";
        $server_browser->recv( my $request1, 4096, POSIX::MSG_PEEK );

        syscall 313, $server_browser_fd, undef, $child_writer_fd, undef, 4096, 1;
        sysread $parent_reader, my $request2, 4096;

        my $response = "200 OK\n<head><title>html</title></head><body>body from $PID</body>";
        syswrite $parent_writer, $response;
        syscall 313, $child_reader_fd, undef, $server_browser_fd, undef, 4096, 1;
#       syswrite $server_browser, "\n"; # eliminates delay, adds syscall...
        sysread $client_browser, my $response1, 4096;
#       chomp $response1;

        if( $response1 ne $response ) {
            warn 'Got wrong response: ', $response1 // 'undef';
            no warnings 'once';
            $DB::single = 1;
        }
    }
}

1;
And here is a sample of the strace output:

Code:
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 8 <0.000010>
setsockopt(8, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 <0.000006>
bind(8, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 <0.000008>
listen(8, 5)                            = 0 <0.000008>
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 9 <0.000006>
connect(9, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 <0.000037>
accept(8, {sa_family=AF_INET, sin_port=htons(49361), sin_addr=inet_addr("127.0.0.1")}, [16]) = 10 <0.000007>
write(9, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 41) = 41 <0.000014>
recvfrom(10, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096, MSG_PEEK, {sa_family=0x8b60 /* AF_??? */, sa_data="(\10\2\0\300\321\177\0\0\1\0\0\0\0"...}, [0]) = 41 <0.000007>
splice(0xa, 0, 0x5, 0, 0x1000, 0x1)     = 41 <0.000007>
read(4, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096) = 41 <0.000005>
write(7, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 67) = 67 <0.000005>
splice(0x6, 0, 0xa, 0, 0x1000, 0x1)     = 67 <0.000007>
read(9, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 4096) = 67 <0.200331>
write(9, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 41) = 41 <0.000016>
recvfrom(10, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096, MSG_PEEK, {sa_family=0x8b60 /* AF_??? */, sa_data="(\10\2\0\300\321\177\0\0\1\0\0\0\0"...}, [0]) = 41 <0.000008>
splice(0xa, 0, 0x5, 0, 0x1000, 0x1)     = 41 <0.000006>
read(4, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096) = 41 <0.000005>
write(7, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 67) = 67 <0.000005>
splice(0x6, 0, 0xa, 0, 0x1000, 0x1)     = 67 <0.000006>
read(9, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 4096) = 67 <0.200622>
write(9, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 41) = 41 <0.000018>
recvfrom(10, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096, MSG_PEEK, {sa_family=0x8b60 /* AF_??? */, sa_data="(\10\2\0\300\321\177\0\0\1\0\0\0\0"...}, [0]) = 41 <0.000007>
splice(0xa, 0, 0x5, 0, 0x1000, 0x1)     = 41 <0.000006>
read(4, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096) = 41 <0.000005>
write(7, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 67) = 67 <0.000005>
splice(0x6, 0, 0xa, 0, 0x1000, 0x1)     = 67 <0.000005>
read(9, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 4096) = 67 <0.200649>
Note the ~200ms read(9,...) calls. If I uncomment the line to send a "\n" then there is no delay. What am I doing wrong? Thanks!
 
Old 12-17-2010, 06:49 PM   #2
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 234Reputation: 234Reputation: 234
3 months & no replies.

Did you solve your problem?
  • If so, please provide your solution -- it might help someone else w/ the same problem.
  • If not, would you like some help w/ re-phrasing your question, or providing more info.?
 
Old 12-18-2010, 10:18 AM   #3
bennymack
LQ Newbie
 
Registered: Sep 2010
Posts: 2

Original Poster
Rep: Reputation: 0
I figured it out after a while..

http://stackoverflow.com/questions/3...o-tcp-buffered
 
Old 12-18-2010, 11:14 AM   #4
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 234Reputation: 234Reputation: 234
Thanks for replying. Thanks for the solution. Please consider marking this thread "[Solved]".
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
buffered and unbuffered i/o netrak Linux - Newbie 2 09-18-2009 06:04 AM
kernel_sendmsg function send tcp package would return broken pipe error asert Linux - Kernel 1 06-01-2008 04:07 PM
buffered I/O greghua Programming 5 10-18-2005 09:00 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 04:31 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration