UNIX网络编程(套接字编程)
关于readn,writen 函数
/*
* 日期:2021-8-8
* 作者:2304768518@qq.com
*
* 用来熟悉readn,writen函数,测试的话
* 现在好像不太会,得等到后面一点点
*
* #include <unistd.h>
* int read(int fd,void* buf,size_t count)
* 1.fd表示文件描述符,buf为读取数据的缓冲区,count是请求读取的字节数
* 2.如果读取失败,返回-1,读取成功,返回读取的字符数并将文件的读写位置向后移
* 如果已经读到文件末尾,返回0
*
* 关于readn函数:
* 字节流套接字(TCP套接字)上的read和write函数所表现的行为不同于通常的文件I/O
* 字节流套接字上调用read或write输入或输出的字节数可能比请求的字节数少,因为内核
* 中用于套接字的缓冲区可能已经到达了极限,此时需要调用者再次调用read或write函数,
* 以输入或输出剩余的字节
*
* ssize_t是有符号整型,在32位机器上等同与int,在64位机器上等同与long int
* 有没有注意到,它和long数据类型有啥区别?其实就是一样的。
* size_t 就是无符号型的ssize_t,也就是unsigned long/ unsigned int (在32位下)
* ,不同的编译器或系统可能会有区别,主要是因为在32位机器上int和long是一样的。
* 在64位没有测试,但是参见百度百科,size_t 在64位下是64位,那么size_t的正确定义应该是typedef unsigned long size_t。
*
*/
#include "unp.h"
ssize_t readn(int fd,void *buff,size_t nbytes)
{
ssize_t nleft=nbytes;//还需要读取的字符的数量
ssize_t nread;//已经读取到的字符数量
char *ptr=buff;//在这里做类型转换是为了将地址增加,也就是移动读写指针的位置
//当还需要读取的字符数量等于0时,代表已经将所需要读取的字符全部读出了
while(nleft>0){
if((nread=read(fd,ptr,nleft))==-1){//代表读取内容失败
if(errno==EINTR){//Interrupted function,中断函数
//要再次读取文件夹中的内容
nread=0;
}else{
return(-1);
}
}else if(nread==0){//代表读取到文件尾部
return (0);
}
//代表读取内容成功
nleft-=nread;//还需要读取的字符数量减少
ptr+=nread;//将指针向后移动,地址进行加减就可以
}
ptr=NULL;
return (1);
}
//往一个文件中写东西
//write函数一般不会返回0,当第三个参数为0时,才会返回0
//当出错时,返回-1,否则返回写进去的字符数量
ssize_t writen(int fd,const void * buff,size_t nbytes)
{
ssize_t nleft=nbytes;//需要写的东西的数量
ssize_t nwrite;//已经写进去的数量
const char *ptr=buff;//控制读写的指针
while(nleft>0){
if((nwrite=write(fd,buff,nleft))<=0){//程序出错了
if(nwrite<0&&errno==EINTR){
nwrite=0;
}else{
return(-1);
}
}
nleft-=nwrite;
ptr+=nwrite;
}
ptr=NULL;
return (nbytes);
}
int main(int argc,char ** argv)
{
//打开一个文件,如果这个文件不存在就创建一个文件夹
int fd=open("file",O_RDWR|O_CREAT);
//往那个文件里面写内容
if(write(fd,"hello world!",13)==-1){
//errno("write error");
}
char str[13]="";
int flag;
//将某个文件中读写指针放在最前面
if((lseek(fd,0,SEEK_SET)) == -1 ){
printf("lseek,__LINE__\n");
};
//利用readn函数读取文件中的内容
if((flag=readn(fd,str,13))==-1){
printf("something error\n");
}else if(flag==0){
printf("读到文件末尾了\n");
}else if(flag==1){
printf("读取到的内容是:%s\n",str);
}
//再次将指针移动
if(lseek(fd,0,SEEK_SET)==-1){
printf("lseek,__LINE__\n");
}
read(fd,str,13);
printf("利用read读到的东西是:%s\n",str);
//打开文件file1
int fd1=open("file1",O_RDWR|O_CREAT);
if(writen(fd,"hello world!",13)==-1){
printf("error\n");
}else{
read(fd1,str,13);
printf("写进去的东西为:%s\n",str);
}
}