Linux 网络编程中的read和write函数正确的使用方式
字节流套接字上的read和write函数所表现的行为不同于通常的文件IO,字节流套接字上调用read和write输入或输出的可能比请求的数量少,然而这不是出错的状态,例如某个中端使read和write提前返回,这时就应该继续读和写而不是出错返回了,下面是unp中对read和write函数在socket中的使用的封装。
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
ssize_t readn(int fd,void* buff,size_t nbytes){
ssize_t nleft;
ssize_t nread;
char* ptr;
nleft=(ssize_t)nbytes;
ptr=(char*)buff;
nread=0;
while(nleft>0){
if((nread=read(fd,ptr,nleft))<0){
if(errno==EINTR){
nread=0;
}
else{
return -1;
}
}
else if(nread==0){ //read返回0代表读到EOF
break;
}
else{
nleft-=nread;
ptr+=nread;
}
}
return (nbytes-nread);
}
ssize_t writen(int fd,void* buff,size_t nbytes){
ssize_t nleft;
ssize_t nwrite;
char* ptr;
nleft=(ssize_t)nbytes;
nwrite=0;
ptr=(char*)buff;
while(nleft>0){
if((nwrite=write(fd,ptr,nleft))<=0){ //write返回0代表出错
if(nwrite<0&&errno==EINTR){
nwrite=0;
}
else{
return -1;
}
}
else{
nleft-=nwrite;
ptr+=nwrite;
}
}
return (nbytes);
}
//频繁使用read函数这个效率非常低
ssize_t readline(int fd,void* buff,size_t nbytes){
ssize_t n,rc;
char c,*ptr;
ptr=(char*)buff;
for(n=1;n<nbytes;++n){
again:
if((rc=read(fd,&c,1))==1){
*ptr++=c;
if(c=='\n')
break;
}
else if(rc==0)
return(n-1);
else{
if(errno==EINTR){
goto again;
}
return -1;
}
}
return (n);
}
//下面是一个改进版的但是这个版本使用了static变量,它是线程不安全的
#define MAXLINE 4096
static int read_cnt;
static char* read_ptr;
static char read_buf[MAXLINE];
//先从内核读一些数据到用户空间,在每次都从用户空间中读数据
static ssize_t myread(int fd,char* ptr){
if(read_cnt<=0){
again:
if((read_cnt=read(fd,read_buf,sizeof(read_buf)))<0){
if(errno==EINTR)
goto again;
return -1;
}
else if(read_cnt==0)
return 0;
else
read_ptr=read_buf;
}
read_cnt--;
*ptr=*read_ptr++;
return 1;
}
ssize_t readline(int fd,void* buff,size_t maxlen){
ssize_t n,rc;
char c,*ptr;
ptr=(char*)buff;
for(n=1;n<maxlen;++n){
if((rc=myread(fd,&c))==1){
*ptr++=c;
if(c=='\n')
break;
}
else if(rc==0){
*ptr='\0';
return (n-1);
}
else{
return -1;
}
}
*ptr='\0';
return n;
}
ssize_t readlinebuf(void **vptrtptr){
if(read_cnt)
*vptrvptr=read_ptr;
return read_cnt;
}
Linux 网络编程中的read和write函数正确的使用方式的更多相关文章
- linux网络编程中的shutdown()与close()函数
1.close()函数 int close(int sockfd); //返回成功为0,出错为-1 close 一个套接字的默认行为是把套接字标记为已关闭,然后立即返回到调用进程,该套接字不能再由cl ...
- linux网络编程中INADDR_ANY的含义
INADDR_ANY选项 网络编程中常用到bind函数,需要绑定IP地址,这时可以设置INADDR_ANY INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或&q ...
- 网络编程中的read,write函数
关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illustrated,vol1>(TCP/IP详解卷1). 关于第二层面,依然建议Richard Steve ...
- linux网络编程中的超时设置
1 下面是在网上找到的资料,先非常的感谢. 用setsockopt()来控制recv()与send()的超时 在send(),recv()过程中有时由于网络状况等原因,收发不能预期进行,而设置收发超时 ...
- linux网络编程中的基本概念
int close(int fd)(假设是服务器端) close 关闭了自身数据传输的两个方向.close一个TCP套接字的默认行为是把该套接字标记成已关闭,然后立即返回到调用进程.该套接字描述符不能 ...
- linux网络编程中阻塞和非阻塞socket的区别
读操作 对于阻塞的socket,当socket的接收缓冲区中没有数据时,read调用会一直阻塞住,直到有数据到来才返 回.当socket缓冲区中的数据量小于期望读取的数据量时,返回实际读取的字节数.当 ...
- linux网络编程中需要注意的信号SIGPIPE
在调试cs时,s端循环收,c端循环发,s端意外崩溃后,c端自动退出,终端提示SIGPIPE导致c端退出.man 7 signal: SIGPIPE Term Broken pipe: write to ...
- Linux网络编程中tcp_server和tcp_client函数的封装
本文的主要目的是将server套接字和client套接字的获取,做一个简易的封装,使用C语言完成. tcp_server 服务器端fd的获取主要分为以下几步: 1.创建socket,这一步仅仅 ...
- Linux网络编程——I/O复用之poll函数
一.回顾前面的select select优点: 目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点 select缺点: 1.每次调用 select(),都需要把 fd 集合从用户态拷贝到内核 ...
随机推荐
- 定制rpm包---Yum环境搭建
1.1 在yum服务器上创建yum仓库命令 mkdir -p /application/nginx/html/yum cd /application/nginx/html/yum rz #上传rpm包 ...
- scrollWidth,clientWidth,offsetWiddth,innerWinth 元素定位
getBoundingClientRect()方法.它返回一个对象,其中包含了left.right.top.bottom四个属性,分别对应了该元素的左上角和右下角相对于浏览器窗口(viewport)左 ...
- .NET MVC 二级域名路由的实现
.NET MVC 5以下版本: http://www.cnblogs.com/luanwey/archive/2009/08/12/1544444.html http://blog.maartenba ...
- jquery操作html小技巧
1.隐藏table整列 $("#tableID tr").find('td:eq(N)').hide();
- Java的DAO设计模式
用java的DAO模式实现对一个学生实体的增加,查询操作. 1.建立一个学生实体类 Student.java public class Student { private String sid; pr ...
- 线程UI同步
只用一次: this.Invoke(new MethodInvoker(() => { this.btnGo.Enabled = true; MessageBox.Show("Yeah ...
- eclipse使用jrebel
注:以下都是网上收集整理的,可能不全,仅限于学习和研究使用. JavaRebel是一个工具,主要是用于热加载,比如说在Tomcat之类的应用服务器中,更新了class或者某些资源文件,使用了JRebe ...
- 第2篇 C#数据类型-值类型与引用类型
一 C#内存分配 在应用程序与操作系统之间有一个"中间人"--公共语言运行时(Common Language Runtime,CLR).它为应用程序提供内`存管理,线程管理和远程处 ...
- 实现基于Keepalived主从高可用集群网站架构
背景 上一期我们实现了基于lvs负载均衡集群的电商网站架构,随着业务的发展,网站的访问量越来越大,网站访问量已经从原来的1000QPS,变为3000QPS,目前业务已经通过集群LVS架构可做到随时拓展 ...
- canvas图表(3) - 饼图
原文地址:canvas图表(3) - 饼图 这几天把canvas图表都优化了下,动画效果更加出色了,可以说很逼近echart了.刚刚写完的饼图,非常好的实现了既定的功能,交互的动画效果也是很棒的. 效 ...