在网络编程中读写套接字自然是最基本的操作,但是并没有想像中那么简单,还是有不少注意点的,打算罗列一下常用的读写套接字的系统调用和相关注意点。
一、read/write系统调用
1、阻塞式读写
(1)read
对阻塞式套接字使用read()可能的情况有:
①阻塞 ,此时套接字接收缓冲区中没有数据,直到有数据或出错(收到RST)才会返回。
②立即返回,返回值的情况有:
a、大于0 ,此时要继续读,个人感觉尽管是返回值与要求读的字节数相同还是最好继续读,但是此时可能会 被 阻塞掉,原因是没有再收到数据或者FIN、RST的报文。
b、0 ,此时读到EOF,对端发送了FIN。
c、-1 ,而且errno=EINTR,说明调用read被阻塞了然后被信号中断了,此时需要继续读。除此之外返回-1时说 明出错了,就不要再继续读了。
代码如下:
int readn(int fd,char *buf,int n)
{
int nread=0;
int nleft=n;
char *tmp=buf;
while(nleft)
{
if((nread=read(fd,tmp,nleft))>0)
{
nleft-=nread;
tmp+=nread;
continue;
}
else if(nread==0)//read EOF,recv FIN ,no more data
break;
else if(nread==-1&&errno==EINTR)
{
continue;
}
}
return (n-nleft);
}
(2)write
对一个阻塞的套接字调用write,可能的情况有:
①被阻塞掉,说明当前套接字没有空闲的发送缓冲区可供发送
②返回正值,说明写到
发送缓冲区里面了,还要判断是否等于打算发送的字节数。
③返回0,说明已经写到EOF了,
④返回-1,而且errno=EINTR,说明阻塞期间被中断了需要继续写。
int writen(int fd,const char *buf,int n)
{
int nleft=n;
int nwrite=0;
char *p=buf;
while(nleft)
{
if((nwrite=write(fd,p,nleft))>0)
{
nleft-=nwrite;
p+=nwtire;
}
else if (nwrite==0)
break;
else if(nwrite<0&&errno==EINTR)//中断
continue;
else
break;
}
return (n-nleft);
}
阅读(649) | 评论(0) | 转发(0) |