完整的读写函数
1.写函数write
1 #include <unistd.h> 2 ssize_t write(int fd, const void *buf, size_t count);
write函数将buf中的count字节内容写入到文件描述符fd中。
成功时返回所写入的字节数。返回0表示什么也没有写入,失败时返回-1。并设置errno变量。
在网络程序中,当我们向套接字文件描述符写入时有两种可能:
①write的返回值大于0,表示定稿了部分或者是全部的数据。
②返回值小于0,此时出现了错误:
- 如果错误为EINTR表示在写的时候出现了中断错误,此时需要重启write函数来重新写入.
- 如果为其他错误,则应当退出程序。错误类型详见http://man7.org/linux/man-pages/man2/write.2.html
为了处理以上的情况,我们自己编写一个写函数来处理这几种情况
1 /** 2 *my_write函数将buf中的count字节内容写入到文件描述符fd中 3 *函数成功时,返回 0,失败时返回 -1 4 */ 5 int my_write( int fd, void *buf, size_t count ) 6 { 7 size_t bytes_left; //还没有写入的字节数 8 size_t written_bytes; //已经写入的字节数 9 char *ptr; //从该位置起写入 10 11 //写入之前的初始化 12 ptr = buf; //刚开始时,从buf的起始位置开始写入 13 bytes_left = count; //刚开始时,全部都还没有写入 14 15 //写入操作 16 while( bytes_left > 0 ) // 当来还有未写入的数据时,执行循环 17 { 18 //开始把数据写入到fd 19 written_bytes = write(fd, ptr, bytes_left); //返回实际写入的字节数 20 21 // 写入不成功时进行处理 22 if( written_bytes <= 0 ) 23 { 24 if( errno == EINTR ) // 如果是中断错误,设置写入字节数为0(written_bytes = 0)则重启写入操作 25 { 26 written_bytes = 0; // 表示没有写入 27 continue; // 提前结束此次循环,重启写入操作 28 } 29 else // 如果是其他错误,则退出程序 30 { 31 perror("write error "); 32 return -1; 33 } 34 } 35 36 //写入成功时,重新调剩下的要写入的字节数和要写入数据的位置 37 bytes_left -=written_bytes; //扣除已写入的字节数 38 ptr+=written_bytes; //ptr指向下一次要写入的数据起始位置 39 } 40 41 return 0; 42 }
2.读函数read
1 #include <unistd.h> 2 ssize_t read(int fd, void *buf, size_t count);
read函数从fd中读取count字节的内容,存储在buf中。
函数成功时,返回实际读的字节数,如果返回0表示已经读到文件的末尾。
返回值小于0表示出现了错误,设置errno:
①如果错误为ENITR说明读是由中断引起的,应当重启读操作。
②如果为其他类型的错误,则程序应该退出并用perror()给出出错信息。具体错误详见http://man7.org/linux/man-pages/man2/read.2.html
为了处理以上的情况,我们自己编写一个读函数来处理这几种情况
1 /** 2 *my_read 函数从fd中读取count字节的数据,并存储到buf中 3 *函数成功时返回读取的字节数,失败时返回 -1 4 */ 5 int my_read( int fd, void *buf, size_t count ) 6 { 7 size_t bytes_left; //还没有读取的字节数 8 size_t bytes_read; //已经读取的字节数 9 char *ptr; //存储数据的起始位置 10 11 //读取数据之前的初始化 12 bytes_left = count;//还有count字节的数据没有读取 13 ptr = buf; //读取到的数据存储在buf中 14 //读取数据 15 while( bytes_left > 0 ) // 数据读取没有全部完成,执行循环 16 { 17 bytes_read = read(fd, ptr, bytes_left); // 返回实际读取的数据的长度 18 19 // read函数调用出现错误,进行处理 20 if( bytes_read < 0 ) 21 { 22 if( errno == EINTR ) // 中断引起的错误, 重新启动读取操作 23 { 24 bytes_read = 0; // 没有读取到数据 25 continue; // 提前结束本次循环 26 } 27 else 28 { 29 perror("read error "); 30 return -1; //其他错误则退出程序 31 } 32 } 33 else if( bytes_read == 0 ) 34 { 35 break; //返回0表示fd中已经没有数据了 36 } 37 38 //重新调整还未读取的数据的字节数和数据的存储位置 39 bytes_left -=bytes_read; //扣除已读取的数据 40 ptr += bytes_read; //下一次存储所读取数据的位置 41 } 42 return (count - bytes_left); 43 }
浙公网安备 33010602011771号