服务端
客户端
参考资料
《UNIX环境高级编程(第3版)》
《UNIX网络编程》
《TCP/IP详解(卷一)》
《深入理解计算机系统》
学习方法介绍
IO 第3、5章节 文件系统 第4、6、7章节 并发 第8、10、11章节 多进程并发(信号)第10章 多线程并发第10、11章节 IPC 进程间通信 进程基础(涉及多进程)第8章 守护进程 第13章 进程间通信 第15、16章节
注意事项:
重构
I/O,input & output,是一切实现的基础。
stdio 标准IO sysio 系统调用IO(文件IO)
优先考虑标准I/O
标准IO
stdio: man 3 fopen(); 文件打开 fclose(); 文件关闭 fgetc(); 读取字符 fputc(); 写字符 fgets(); 读取字符串 fputs(); 写字符串 fread(); 读二进制 fwrite(); 写二进制 printf()族 scanf()族 fseek(); ftell(); rewind(); fflush();
标准IO相关结构体FILE
man fopen #include <stdio.h> FILE *fopen(const char *pathname, const char *mode); 参数: pathname,文件路径名 mode,打开模式 r,只读打开,文件指针在beginning of file (不会创建) r+,读写打开,文件指针在文件开始处 (不会创建) w,只写形式打开,有则清空,无则创建,文件指针在文件开始处(文件的第一个有效字节) w+,读写形式打开,有则清空,无则创建,文件指针在文件开始处(文件的第一个有效字节) a,追加写(只有追加写,没有追加读),文件最后一个有效字节的下一个位置(end of file) a+,以读写(追加写)形式打开文件,无则创建, 读:beginning of file,即 文件的第一个有效字节 追加写:end of file,即文件最后一个有效字节的下一个位 注意:区分文件最后一个有效字节与最后一个有效字节的下一个位置 b,二进制,Windows区分字符与二进制 注意,r和r+ 要求文件必须存在,否则结束当前调用,返回错误 返回值: 成功:FILE指针 失败:NULL,errno(errno是全局变量?)
errno定义的位置:
cat /usr/include/asm-generic/errno.h cat /usr/include/asm-generic/errno-base.h
已知条件: char *ptr="abc"; //字符串常量 ptr[0]='x'; 问:是否会得到"xbc"? 答:取决于当前平台使用的编译器会把"abc"放到哪里存储?
int *p = malloc(sizeof(int)); malloc的返回值是void * 如果不添加头文件#include<stdlib.h>, gcc会认为所有函数的返回值是int(有例外),将int型赋值给int *必然会报错
man perror perror - print a system error message man strerror #include <string.h> char *strerror(int errnum); //return string describing error number
打开不同的注释,观察执行结果
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> int main (){ FILE *fp; fp= fopen("tmp","r"); if(fp==NULL){ //fprintf(stderr,"fopen error! errno= %d \n",errno); perror("fopen()"); //fprintf(stderr,"fopen():%s\n",strerror(errno)); exit(1); } puts("fopen OK!"); exit(0); }
思考:
FILE *fopen(const char *pathname, const char *mode);
调用fopen返回的FIEL结构体保存在哪里? 1. 栈? 2. 静态区? 3. 堆?
FILE *fopen(const char *pathname, const char *mode); { FILE tmp; //局部变量?? ❌ tmp.xx=uu; ... return tmp; ---------------------------------------- static FILE tmp; //静态区?? ❌ 后打开的会覆盖先打开的 tmp.xx=vv; ... return tmp; ---------------------------------------- FILE *tmp = NULL; //放在堆?? ✔ tmp = malloc (sizeof FILE); // tmp->xx=ww; ... return &tmp; } fopen fclose //如果一个函数的返回值是指针,并且该函数有一个逆操作,通常这样的函数的返回值指针存储在堆上
man fclose fclose - close a stream 关闭流 #include <stdio.h> //头文件 int fclose(FILE *stream); //函数原型
在不更改当前默认环境的情况下,一个进程默认打开3个stream流:
可通过ulimit -a
查看,通过ulimit -n xxx
更改对应的值
user@ubuntu:~/codes$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 15374 max locked memory (kbytes, -l) 65536 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 15374 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
0666 & ~umask 110 110 110 ---0666 000 000 010 ---0002 0666 与umask取反相与 111 111 101 ---~umask 110 110 110 ---0666 110 110 100 ---0666 & ~umask 相与的结果 即664 rw-rw-r--
lry@ubuntu:~/codes$ ll tmp -rw-rw-r-- 1 lry lry 0 9月 30 23:16 tmp
待学习fgetc fputc。。。。。