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()
区别和用途
第15章 unix 域协议(本地套接字)
用于本地socket 连接,主要用途是IPC 进程间通信
socket(AF_LOCL,...);
socketpair()