Chinaunix首页 | 论坛 | 博客
  • 博客访问: 166496
  • 博文数量: 46
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 396
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-03 12:59
文章分类

全部博文(46)

文章存档

2010年(1)

2009年(2)

2008年(43)

我的朋友

分类: C/C++

2008-04-03 21:15:05

最近在编写利用套接口传输数据的程序时,发现如果直接利用read和write函数来实现对套接口数据的读写,若传输较小的文件基本上可以成功的传输和接受,但在传输较大文件,如百兆的视频文件时,则接受端会出现write error:bad address的情况。查了些资料,才将问题原因基本查明,总结如下:
      字节流套接口上的read和write函数表现的行为不同于通常的文件I/O。字节流套接口上的读写字节数可能比要求的数量少,原因时内核中套接口的缓冲区可能已经达到极限。此时就需要调用者再次调用read和write函数,将剩余的字节输入和输出。有些版本的unix在往一个管道中写入多于4096字节的数据时会表现这样的行为。这种现象在读取套接口时很常见,在写字节流接口时只能在套接口非阻塞的情况下才出现。我们可以通过编写另外的readn函数和writen函数来预防这种现象。
 ssize_t readn(int fd,void *vptr,size_t n)
{
       size_t nleft;
       ssize_t nread;
       char *ptr;
       ptr=vptr;
       nleft=n;
       while(nleft>0)
              {
              if((nread=read(fd,ptr,nleft))<0)
                     {
                     if(errno==EINTR)
                            nread=0;
                     else
                            {
                            perror("\nread");
                            return(-1);
                            }
                     }
              else if(nread==0)
                     {
                     break;
                     }
              nleft-=nread;
              ptr =nread;
              }
       return(n-nleft);
}
 
ssize_t writen(int fd,const void *vptr,size_t n)
{
       size_t nleft;
       ssize_t nwritten;
       const char *ptr;
       ptr=vptr;
       nleft=n;
       while(nleft>0)
              {
                     if((nwritten=write(fd,ptr,nleft))<=0)
                            {
                                   if(nwritten<0&&errno==EINTR)
                                          nwritten=0;
                                   else
                                          {
                                          perror("\nwrite");
                                          return(-1);
                                          }
                            }
                                   nleft-=nwritten;
                                   ptr =nwritten;
                            }
                     return (n);
              }
通过使用readn和writen这两个自定义的函数,可以保证对套接口的读写是指定数量的字节数。
参考《UNIX网络编程》第一卷,套接口API
阅读(3613) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:I/O 复用Select函数几点注意

给主人留下些什么吧!~~