메모리와 파일 간에 직접 데이터를 전송할 수 있다.
rio_readn
현재 파일 식별자 fd에서 n 만큼의 데이터를 버퍼 usrbuf로 보낸다.
#include "csapp.h"
ssize_t rio_readn(int fd, void* usrbuf, size_t n)
rio_writen
현재 메모리의 버퍼 usrbuf에서 n 만큼의 데이터를 파일 식별자 fd로 보낸다.
#include "csapp.h"
ssize_t rio_writen(int fd, void* usrbuf, size_t n);
텍스트 라인 전체를 내부 읽기 버퍼에서 복사하는
rio_readlineb
와 텍스트 라인과 바이너리 데이터 모두를 읽을 수 있는rio_readnb
.
파일 → 읽기 버퍼 → (읽기 버퍼를 읽고 그 데이터를)메모리 버퍼로 복사
rio_t 구조체
#define RIO_BUFSIZE 8192
typedef struct {
int rio_fd; /* Descriptor for this internal buf */
int rio_cnt; /* Unread bytes in internal buf */
char *rio_bufptr; /* Next unread byte in internal buf */
char rio_buf[RIO_BUFSIZE]; /* Internal buffer */
} rio_t;
rio_readinitb
읽고 싶은 파일 식별자
fd
와 읽기 버퍼rp
를 연결한다.
#include "csapp.h"
void rio_readinitb(rio_t *rp, int fd)
{
rp->rio_fd = fd;
rp->rio_cnt = 0; /* unread size 라고는 하는데 사용하는 걸 보면 read size 라고 봐야 된다.... */
rp->rio_bufptr = rp->rio_buf; /* 내부 버퍼 포인터 */
}
rio_readlineb
텍스트 라인 전체를 내부 읽기 버퍼
rp
에서 읽은 후, 메모리 버퍼usrbuf
으로 복사하고,\\0(NULL)
로 텍스트 라인을 종료시킨다.
최대 maxlen-1
바이트 만큼 읽고 마지막 1바이트는 \\0
을 넣어준다.
ssize_t rio_readlineb(rio_t* rp, void* usrbuf, size_t maxlen)
{
int n, rc;
char c, *bufp = usrbuf;
for (n = 1; n < maxlen; n++) {
if ((rc = rio_read(rp, &c, 1)) == 1) {
*bufp++ = c;
if (c == '\\n') {
n++;
break;
}
} else if (rc == 0) {
if (n == 1)
return 0; /* EOF, no data read */
else
break; /* EOF, some data was read */
} else
return -1; /* Error */
}
*bufp = 0;
return n-1;
}
rio_readnb
텍스트 라인과 바이너리 데이터 모두를 읽을 수 있다. n 바이트씩 가져온다.
ssize_t rio_readnb(rio_t* rp, void* usrbuf, size_t n)
{
size_t nleft = n;
ssize_t nread;
char *bufp = usrbuf;
while (nleft > 0) {
if ((nread = rio_read(rp, bufp, nleft)) < 0)
return -1; /* errno set by read() */
else if (nread == 0)
break; /* EOF */
nleft -= nread;
bufp += nread;
}
return (n - nleft); /* return >= 0 */
}
서버와의 연결 후 클라이언트와 통신한다.