unix network programming(3rd)Vol.1 [第13~15章]《读书笔记系列》

时间:2023-03-08 19:43:20
unix network programming(3rd)Vol.1 [第13~15章]《读书笔记系列》

第13章 守护进程和inetd 超级服务器

syslog()
daemon_init()
setuid()
setgid()

第14章 高级IO

标准I/O函数库,支持3种缓冲

缓冲(读写存储设备(硬盘),或者网络 合并读写,可以大大提高性能, 当然也可以不合并; 每次读写操作就立即 发送到指定输入输出(写进硬盘))

  • 全缓冲(fully buffering):意味着只在出现下列情况才发生I/O

    1.缓冲区满

    2.进程显示调用fflush

    3.进程调用exit终止自己

    标准IO缓冲区的大小 通常为8192 byte

  • 行缓冲(line buffering):意味着只在出现下列情况才发生I/O

    1.换行符

    2.进程显示调用fflush

    3.进程调用exit终止自己

  • 不缓冲(unbuffering): 意味着每次调用标准I/O输出函数,都才发生I/O


套接字超时(3种 都适用于输入输出 例如 read、write、recvfrom、sendto; 第三种只支持套接字描述符; )

1)调用alarm,它在指定超时期满时产生SIGALRM信号。这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm调用。

//产生SIGALRM信号,为connect设置超时

{ 代码见书...}

//产生SIGALRM信号,为recvfrom设置超时

{ 代码见书...}

2)在select中阻塞等待IO(select 有内置的时间限制) 以此代替直接阻塞在read、write上的调用

//用select 为recvfrom设置超时
int readable_timeo(int fd,int sec){ //--- lib/readable_timeo.c
fd_set rset;
struct timeval tv;
FD_ZERO(&rset);
FD_SET(fd, &rset);
tv.tv_sec = sec;
tv.tv_usec = 0;
return (select (fd+1, &rset,NULL,NULL,&tv)); //>0 if descriptor is readable
}

3)使用较新的SO_RCVTIMEO和SO_SNTIMEO 套接字选项。这个方法的问题在于并非所有的实现 都支持这两个套接字选项。(只支持套接字描述符)

//用SO_RCVTIMEO为recvfrom设置超时
void dg_cli(FILE *fp, int sockfd,const SA*pservaddr,socklen_t servlen)
{ //--- advio/dgclitimeo.c
int n;
char sendline[MAXLINE],recvline[MAXLINE+1];
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
Setsockopt(sockfd, SOL_SOCKET, SO_RECVTIMEO, &tv, sizeof(tv));
while(Fgets(sendline, MAXLINE, fp)!= NULL){
Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
n= recvfrom(sockfd, recvline, MAXLINE, 0,NULL,NULL);
if(n<0){
if(errno == EWOULDBLOCK){
fprintf(stderr,"socket timeout! \n");
contine;
}else
err_sys("recvfrom error \n");
}
recvline[n] =0;//null terminate
Fputs(recvline, stdout);
}

http://linux.die.net/man/2/read

http://linux.die.net/man/2/write

http://linux.die.net/man/2/pwrite

 #include <unistd.h>
ssize_t read(int fd, void *buf, size_t count); //read - read from a file descriptor
ssize_t write(int fd, const void *buf, size_t count); //write - write to a file descriptor //pread, pwrite - read from or write to a file descriptor at a given offset
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);

http://linux.die.net/man/2/recv

http://linux.die.net/man/2/send

 //recv, recvfrom, recvmsg - receive a message from a socket
//send, sendto, sendmsg - send a message on a socket
#include <sys/types.h>
#include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

http://linux.die.net/man/2/readv

http://linux.die.net/man/2/writev

 #include <sys/uio.h>
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);//分散输入 The readv() system call reads iovcnt buffers from the file associated with the file descriptor fd into the buffers described by iov ("scatter input").
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);//集中输出 The writev() system call writes iovcnt buffers of data described by iov to the file associated with the file descriptor fd ("gather output").
ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);

http://linux.die.net/man/3/aio_read

#include <aio.h>

int aio_read(struct aiocb *aiocbp); //aio_read - asynchronous read   异步读
int aio_write(struct aiocb *aiocbp); //aio_write - asynchronous write 异步写
aio_一系列......

read() recv() recvv() revcfrom() revcmsg()

write() send() sendv() sendto() sendmsg()

aio_read() aio_write()

区别和用途

unix network programming(3rd)Vol.1 [第13~15章]《读书笔记系列》


第15章 unix 域协议(本地套接字)

用于本地socket 连接,主要用途是IPC 进程间通信

socket(AF_LOCL,...);

socketpair()