TCP/IP网络编程学习笔记(二)

1.2基于Linux的文件操作

在Linux里,socket被视为文件的一种,因此在网络传输过程中可以使用文件I/O的函数。
而Windows区分文件和socket,因此需要调用特殊的数据传输函数

底层文件访问(Low-Level File Access)和文件描述符(File Descripter)

文件描述符是操作系统分配给文件或套接字的整数
文件和套接字一般经过创建过程后才会被分配文件描述符。有三种特殊的对象,即使未经过创建过程,程序开始运行后也会被自动分配文件描述符。

文件描述符对象
0标准输入:Standard Input
1标准输出:Standard Output
2标准错误:Standard Error

打开文件

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int open(const char *path,int flag);

成功时返回文件描述符,失败时返回-1
path: 文件名的字符串地址
flag: 文件打开模式信息

打开模式含义
O_CREATE必要时创建文件
O_TRUNC删除全部数据
O_APPEND维持现有数据,保存到其后面
O_RDONLY只读打开
O_WRDONLY只写打开
O_RDWR读写打开

关闭文件

#include<unistd.h>
int close(int fd);

成功时返回0,失败时返回-1
fd: 需要关闭的文件或套接字的文件描述符
注意: 此函数不仅可以关闭文件,还可以关闭套接字。

将数据写入文件

#include<unistd.h>

ssize_t write(int fd,const void * buf,size_t nbytes);

成功时返回写入的字节数,失败时返回-1
fd: 数据传输对象的文件描述符
buf: 保存要传输的数据的缓冲地址值
nbytes: 要传输数据的字节数

创建新文件并保存数据的完整程序:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

void error_handling(char* message);

int main(void)
{
	int fd;
	char buf[]="Let's go!\n";
	
	fd=open("data.txt", O_CREAT|O_WRONLY|O_TRUNC);
	if(fd==-1)
		error_handling("open() error!");
	printf("file descriptor: %d \n", fd);

	if(write(fd, buf, sizeof(buf))==-1)
		error_handling("write() error!");

	close(fd);
	return 0;
}

void error_handling(char* message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

第13行:文件打开模式为O_CREAT|O_WRONLY|O_TRUNC组合,表示创建空文件,并只能写,若已有同名文件则清空全部数据
第18行:向fd中保存的文件描述符对应的文件传输buf中保存的数据

Linux下运行结果:
在这里插入图片描述

读取文件中的数据

#include<unistd.h>

ssize_t read(int fd,void * buf,size_t nbytes);

fd: 显示数据接收对象的文件描述符
buf: 要保存接收数据的缓冲地址
nbytes: 要接受数据的最大字节数

读取文件中的数据 完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#define BUF_SIZE 100

void error_handling(char* message);

int main(void)
{
	int fd;
	char buf[BUF_SIZE];
	
	fd=open("data.txt", O_RDONLY);
	if( fd==-1)
		error_handling("open() error!");
	
	printf("file descriptor: %d \n" , fd);
	
	if(read(fd, buf, sizeof(buf))==-1)
		error_handling("read() error!");

	printf("file data: %s", buf);
	
	close(fd);
	return 0;
}

void error_handling(char* message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

第15行: 打开读取文件专用的文件data.txt
第21行: 调用read函数,向buf数组保存读入的数据

以上是基于文件描述符的I/O操作

文件描述符和套接字

下面是同时创建文件和套接字,并用整数型态比较返回的文件描述符值的完整代码(综合以上创建文件描述符、创建文件的知识点)

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>

int main(void)
{	
	int fd1, fd2, fd3;
	fd1=socket(PF_INET, SOCK_STREAM, 0);
	fd2=open("test.dat", O_CREAT|O_WRONLY|O_TRUNC);
	fd3=socket(PF_INET, SOCK_DGRAM, 0);
	
	printf("file descriptor 1: %d\n", fd1);
	printf("file descriptor 2: %d\n", fd2);
	printf("file descriptor 3: %d\n", fd3);
	
	close(fd1);
	close(fd2);
	close(fd3);
	return 0;
}

第9行:创建TCP连接的套接字
第11行:创建UDP连接的套接字
第10行:创建test.dat文件

第17-19行:输出上面创建的三个文件描述符的整数值

运行结果

在这里插入图片描述
从输出的文件描述符可以看出,描述符从3开始以由小到大的顺序编号
编号0、1、2是分配给标准I/O的描述符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值