当前位置:网站首页>Preliminary solution of i/o in socket programming

Preliminary solution of i/o in socket programming

2022-06-25 21:42:00 ypd.

What is part of a socket I/O

  • in many instances , When executing on a streaming socket I/O It will appear during operation Partial reading and Partial write The phenomenon of
  • perform read() and write() When the system is called , In some cases , There may be Transmitted data Less than Requested data

When will this phenomenon occur

  • read():
    • Available data ratio read() Less data requested , here read() Returns the number of bytes available
  • write():
    • write() After transmitting some requested bytes, it is interrupted by the signal processing process
    • Socket works in non blocking mode (O_NONBLOCK), Probably Only part of the transmission
    • An asynchronous error occurred after some of the requested bytes had been transferred

How to solve

  • The system call can be called again to complete the transmission of all data
  • We are right. read() And write() Construct their respective wrapping functions , It can call the corresponding system call circularly , Ensure that the requested number of bytes can always be fully transmitted
    - Unless If something goes wrong or read() Detected. EOF

SHOW ME THE CODE

  • readn()
/* readn()  The parameters of read() identical   It's recycled read() system call   Ensure that the requested number of bytes is always fully transmitted  ssize_t readn(int fd, void *buffer, size_t count); return number of bytes read, 0 on EOF, -1 on failure */

#include <unistd.h>
#include <errno.h>

//ssize_t read(int fildes, void *buf, size_t nbyte);
ssize_t readn(int fd, void *buffer, size_t n)
{
    
    /* ssize_t : signed long \ signed Type is only for processing read return -1 The situation of , Nothing else  size_t : unsigned long */
    ssize_t numRead;        // * of Bytes fetched by last read()
    size_t totRead;         // Total * of bytes read so far
    char *buf;

    buf  = buffer;
    for(totRead = 0; totRead < n; ){
    
        numRead = read(fd, buf, n-totRead);

        if(numRead == 0){
       // EOF
            return totRead; // may be 0 if this is first read()
        }
        if(numRead == -1){
    
            if(errno == EINTR){
    
                continue;   // interrupted -> restart read()
            }else{
    
                return -1;  // some other error
            }
        }
        totRead += numRead;
        buf += numRead;     // offset
    }

    return totRead;         // must be 'n' Bytes if we get here
}
  • writen()
/* writen()  The parameters of write() identical   It's recycled write() system call   Ensure that the requested number of bytes is always fully transmitted  ssize_t writen(int fd, void *buffer, size_t count); return number of bytes written, -1 on failure */

#include <unistd.h>
#include <errno.h>

//ssize_t write(int fildes, const void *buf, size_t nbyte);
ssize_t writen(int fd, void *buffer, size_t n)
{
    
    /* ssize_t : signed long size_t : unsigned long */
    ssize_t numWritten;         // * of Bytes fetched by last read()
    size_t totWritten;          // Total * of bytes read so far
    char *buf;

    buf = buffer;
    for(totWritten = 0; totWritten < n; ){
    
        numWritten = read(fd, buf, n-totWritten);

        if(numWritten <= 0){
    
            if(numWritten == -1 && errno == EINTR){
    
                continue;       // Interrupted -> restart write()
            }else{
    
                return -1;
            }
        }

        totWritten += numWritten;
        buf += numWritten;
    }

    return totWritten;         // must be 'n' Bytes if we get here
}

Reference resources

  • 《TLPI》
原网站

版权声明
本文为[ypd.]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206251844065235.html