精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
要点
char *tmp; int rc,n=nbytes;
tmp=buf; while((rc=read(sd,tmp,n))>0) { n-=rc; tmp+=rc; if(n<=0) break; }
这样写是确保收到足够的数据。
更简短的形式为:
for(n=nbytes,tmp=buf;n>0;tmp+=rc,n-=rc) if((rc=read(sd,temp,n))<0) break;
ssize_t readit(int sd,char *buf,int nbytes) { int n; char *tmp; tmp=buf; n=nbytes; while(n>0) int rc=read(sd,tmp,n); if(rc>0) {/*main case,successful read of some bytes主要的分支,成功读取了一些字节数*/ n-=rc; tmp+=rc; continue; } if(rc==0) /*end of file遇到文件结束*/ break; /*reached here only if error,rc<0只在错误时才能执行到这一点*/ if(errno==EINTR) /*interrupted by a signal信号中断*/ continue; return(-1); } return (nbytes-n); }
if(rc==0) /*end of file*/ break;除非你使用了非阻塞写操作,你不会得到返回0情况。
#include <sys/types.h>
#include <sys/socket.h>
int send(int sd,const void *buf,size_t len,int flags);
int recv(int sd, void *buf,size_t len,int flags);
MSG_OOB:发送带外数据(高优先数据,后发先到);两个类型(SOCK_STREAM这样的分类)的socket和协议(TCP这样的分类)必须支持这个。对于TCP,它应该只是一个字节数据,被认为是紧急请求。
MSG_DONTROUTE:目标是在本机网络上,所以不通过网关路由。通常在检测或路由程序里使用这个标志。和设置socket的SO_DONTROUTE选项功效一样。
MSG_DONTWAIT:在I/O操作上不阻塞;如果操作会阻塞,EAGAIN会返回。这和设置socket选项O_NONBLOCK效果一样,设置要用fcntl()函数。
MSG_NOSIGNAL:在流式socket处理遇到对方中断连接时不发送SIGPIPE信号;EPIPE依然会做为错误返回出来。
MSG_CONFIRM:通知链接层,有一个对端发来的回复成功接收到了。这个只对SOCK_DRGRAM和SOCK_RAW有效,也只适用于TCP。这是Linux才扩展出来的功能。
MSG_OOB:考虑接收带外数据。
MSG_PEEK:在接收缓冲里检查数据,但是不从队列里丢弃。
MSG_WAITALL:阻塞,直到要求的字节数接收完全,或信号捕获到了,或连接断开,或错误发生。
MSG_NOSIGNAL:在流式socket处理遇到对方中断连接时不发送SIGPIPE信号;EPIPE依然会做为错误返回出来。
#include <sys/types.h>
#include <sys/socket.h>
int sendto(int sd,const void*buf,size_t len,int flags,const struct sockaddr*to,socklen_t tolen);
int recvfrom(int sd,void*buf,size_t len,int flags,struct sockaddr*from,socklen_t*fromlen);