Recv, send, read, write return values for socket blocking and non-blocking cases

Source: Internet
Author: User

Original posts: http://blog.csdn.net/nodeathphoenix/article/details/23284157

One, the pipe read and write rules

When there is no data to read

    • O_nonblock Disable:read Call blocking, that is, the process pauses execution until the data arrives.
    • The O_nonblock enable:read call returns a -1,errno value of Eagain.

When the pipes are full

    • O_nonblock Disable:write call blocked until a process reads the data.
    • O_nonblock Enable: Call returns -1,errno value of Eagain

Read returns 0 if the corresponding file descriptor for all pipe writes is closed

The write operation generates a signal if the file descriptor corresponding to the read end of all the pipes is closed sigpipe

When the amount of data to be written is <=pipe_buf, Linux guarantees the atomicity of the write.

Linux will no longer guarantee the atomicity of writes when the amount of data to be written is >pipe_buf.

Detail See also:

Http://man7.org/linux/man-pages/man7/pipe.7.html

Second, verify the exampleExample One: O_nonblock disable:read (blocking) call blocking, that is, the process pauses execution until the data arrives.
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> int main (void) {    int fds[2];    if (pipe (FDS) = =-1) {        perror ("pipe error");        Exit (exit_failure);    }    pid_t pid;    PID = fork ();    if (PID = =-1) {        perror ("fork Error");        Exit (exit_failure);    }    if (PID = = 0) {        close (fds[0]);//Sub-process close the read end of        Sleep (ten);        Write (fds[1], "Hello", 5);        Exit (exit_success);    }    Close (fds[1]);//parent process Close Write-end    char buf[10] = {0};    Read (fds[0],buf,10);    printf ("Receive datas =%s\n", buf);    return 0;}

Results:

Description: A file descriptor was opened by default when the pipeline was created and blocked (block) mode is turned on by default

So here we let the child process sleep 10s, the parent process is blocked because no data is read from the pipeline, until the child process sleeps, and the parent process reads the data when the data is written to the pipeline

Example Two: O_nonblock enable: Aread (non-blocking) call returns a -1,errno value of Eagain.
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> int main (void) {    int fds[2];    if (pipe (FDS) = =-1) {        perror ("pipe error");        Exit (exit_failure);    }    pid_t pid;    PID = fork ();    if (PID = =-1) {        perror ("fork Error");        Exit (exit_failure);    }    if (PID = = 0) {        close (fds[0]);//Sub-process close the read end of        Sleep (ten);        Write (fds[1], "Hello", 5);        Exit (exit_success);    }    Close (fds[1]);//parent process Close Write-end    char buf[10] = {0};    int flags = FCNTL (Fds[0], F_GETFL);//First get the original flags    Fcntl (Fds[0],f_setfl,flags | O_nonblock);//Set FD to block mode    int ret;    ret = read (fds[0],buf,10);    if (ret = =-1) {        perror ("read error");        Exit (exit_failure);    }    printf ("Receive datas =%s\n", buf);    return 0;}

Results:

Example Three:read corresponds to write end : Read returns 0 if the corresponding file descriptor for all pipe writes is closed
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> int main (void) {    int fds[2];    if (pipe (FDS) = =-1) {        perror ("pipe error");        Exit (exit_failure);    }    pid_t pid;    PID = fork ();    if (PID = =-1) {        perror ("fork Error");        Exit (exit_failure);    }    if (PID = = 0) {        close (fds[1]);//Sub-process close write        exit (exit_success);    }    Close (fds[1]);//parent process Close Write-end    char buf[10] = {0};    int ret;    ret = read (fds[0],buf,10);    printf ("ret =%d\n", ret);    return 0;}

Results:

It does return 0, indicating that the end of the file is read and does not indicate an error

Example four:write corresponds to read end off: The write operation generates a signal if the file descriptor corresponding to the read end of all pipes is closed sigpipe
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include < Signal.h>void sighandler (int signo); int main (void) {    int fds[2];    if (signal (sigpipe,sighandler) = = Sig_err)    {        perror ("Signal error");        Exit (exit_failure);    }    if (pipe (FDS) = =-1) {        perror ("pipe error");        Exit (exit_failure);    }    pid_t pid;    PID = fork ();    if (PID = =-1) {        perror ("fork Error");        Exit (exit_failure);    }    if (PID = = 0) {        close (fds[0]);//Sub-process close read        exit (exit_success);    }    Close (fds[0]);//The parent process closes the read end of    sleep (1);//ensures that the child process also closes the read end    int ret;    ret = Write (fds[1], "Hello", 5);    if (ret = =-1) {        printf ("Write error\n");    }    return 0;} void Sighandler (int signo) {    printf ("Catch a sigpipe signal and Signum =%d\n", Signo);}

Results:

When all read ends are turned off, the sigpipe signal is actually generated when write

Example Five: o_nonblock disable: write (block) call blocked until a process reads data
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> int main (void) {    int fds[2];    if (pipe (FDS) = =-1) {        perror ("pipe error");        Exit (exit_failure);    }    int ret;    int count = 0;    while (1) {        ret = write (fds[1], "A", 1),//fds[1] default is the blocking mode        if (ret = =-1) {            perror ("write error");            break;        }        count++;    }    return 0;}

Results:

Description: The default is blocking mode when FD is turned on, and when the pipe buffer is full, the write operation does block, waiting for other processes to take the data out of the pipeline

Example Six: O_nonblock enable:write (non-blocking) call returns a -1,errno value of Eagain
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> int main (void) {    int fds[2];    if (pipe (FDS) = =-1) {        perror ("pipe error");        Exit (exit_failure);    }    int ret;    int count = 0;    int flags = FCNTL (FDS[1],F_GETFL);    Fcntl (fds[1],f_setfl,flags| O_nonblock);    while (1) {        ret = write (fds[1], "A", 1),//fds[1] default is the blocking mode        if (ret = =-1) {            perror ("write error");            break;        }        count++;    }    printf ("The pipe capcity is =%d\n", count);    return 0;}

Results:

Egin error also occurs, pipeline capacity is 65536 bytes

Man 7 Pipe Description:

Pipe capacity
       A pipe has a limited capacity.  If the pipe is full and then a write (2)       flag was set       (see below).  Different implementations has Different limits for the       pipe capacity.  Applications should not rely on a particular       Capacity:an application should being designed so a reading process
   
    consumes data as soon as it is available, so a writing process       does not remain blocked.       In Linux versions before 2.6.11, the capacity of a pipe is the same       as the system page size (e.g., 4096 bytes on i38 6).  Since Linux       2.6.11, the pipe capacity is 65536 bytes.
   
Third, the relationship between pipeline writing and Pipe_buf
Man Help Description:
Pipe_buf
posix.1-2001 says that write (2) s of less thanPipe_bufBytes must be atomic:the output data are written to the pipe as a contiguous sequence. Writes of more thanPipe_bufBytes May is nonatomic:the kernel may interleave the data and data written by other processes. POSIX.1-2001 requiresPipe_bufTo is at least bytes. (On Linux,Pipe_bufis 4096 bytes.) The precise semantics depend on whether the file descriptor is nonblocking (O_nonblock), whether there is multiple writers to the pipe, and onNThe number of bytes to is written:O_nonblockDisabledN<=Pipe_bufAllNBytes is written atomically; Write (2) may block if there are not guest forNBytes to is written immediately blocking mode and N<pipe_buf: Write is atomic, if there is not enough space for n bytes to write all, block until there is enough space to write n bytes all to the pipeO_nonblockEnabledN<=Pipe_bufIf there is the to-writeNbytes to the pipe and then write (2) succeeds immediately, writing allNbytes otherwise write (2) fails, witherrnoSet toEagain. Non-blocking mode and N&LT;PIPE_BUF: Writes are atomic, all are successfully written immediately, otherwise none are written, and an error is returnedO_nonblockDisabledN>Pipe_bufThe write is nonatomic:the data given to write (2) may be interleaved with write (2) s by other process; The Write (2) blocks untilNBytes has been written. Blocking mode and n>pipe_buf: No atomicity, there may be other processes in the middle of writing until all n bytes are written back, otherwise blocking waits to be writtenO_nonblockEnabledN>Pipe_bufIf the pipe is full and then write (2) fails, witherrnoSet toEagain. Otherwise, from 1 toNBytes may written (i.e), a "partial write" may occur; the caller should check the return Valu E from write (2) to see how many bytes were actually written), and these bytes could be interleaved with writes By the other processes.
   Non-blocking mode and N>PIPE_BUF: If the pipe is full, it fails immediately, one does not write, an error is returned, and if it is dissatisfied, the number of bytes written is 1~n, that is, a partial write, and there may be other processes interspersed by writing
    • When the amount of data to be written is not greater than PIPE_BUF, Linux guarantees the atomicity of the write.
    • When the amount of data to be written is greater than Pipe_buf, Linux will no longer guarantee the atomicity of writes.

NOTE: Pipe capacity is not necessarily equal to PIPE_BUF

Example: When writing data greater than pipe_buf

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys /types.h> #include <errno.h> #include <fcntl.h> #define ERR_EXIT (m) do {Perro                 R (M);         Exit (Exit_failure);    } while (0) #define Test_size 68*1024int Main (void) {char a[test_size];    Char B[test_size];    Char C[test_size];    Memset (A, ' a ', sizeof (a));    memset (b, ' B ', sizeof (b));    memset (c, ' C ', sizeof (c));    int pipefd[2];    int ret = pipe (PIPEFD);    if (ret = =-1) err_exit ("Pipe error");    pid_t pid;    PID = fork ();        if (PID = = 0)//first child process {close (pipefd[0]);        ret = Write (pipefd[1], a, sizeof (a));        printf ("apid=%d write%d bytes to pipe\n", Getpid (), ret);    Exit (0);        } PID = fork ();        if (PID = = 0)//second sub-process {close (pipefd[0]);        ret = Write (pipefd[1], B, sizeof (b));        printf ("bpid=%d write%d bytes to pipe\n", Getpid (), ret);Exit (0);        } PID = fork ();        if (PID = = 0)//third sub-process {close (pipefd[0]);        ret = Write (pipefd[1], C, sizeof (c));        printf ("bpid=%d write%d bytes to pipe\n", Getpid (), ret);    Exit (0);        } close (pipefd[1]);    Sleep (1); int fd = open ("Test.txt", O_wronly | O_creat |    O_trunc, 0644);    Char Buf[1024*4] = {0};    int n = 1;        while (1) {ret = read (Pipefd[0], buf, sizeof (BUF));        if (ret = = 0) break;        printf ("n=%02d pid=%d read%d bytes from pipe buf[4095]=%c\n", n++, Getpid (), ret, buf[4095]);    Write (FD, buf, ret);    } return 0; }

Results:

There is an interleaved write between the child processes, and there is no guarantee of an atomic write, and the parent process reads while the child process is written.

Recv, send, read, write return values for socket blocking and non-blocking cases

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.