并发多进程服务器网络聊天模型

这两天在想,到底是否学会了,怎么验证你学会了,我一直在纠结,但是昨天早上醒来,我觉得我可能迄今为止做错了很多事,比葫芦画瓢?谁都会,靠着自己脑中残留的记忆来照着写,真的是硬实力吗?我不觉得,我认为只有自己写出来了,才算你牛逼。

这两天虽然只写了不多的代码,但我觉得让我受益匪浅。把遇到的问题即时记录下来则会很有帮助。
1.warning的警告要看在哪里警告,警告的提示跟函数参数的出入在哪,我的问题在于编译时提示我recvfrom的参数有问题,

环形队列数据读写实现

在此项目中,创建了一个信号量集合并包含了三个信号量.

使用一个信号量 (SEM_MUTEX) 用于共享内存的互斥.
使用两个信号量(SEM_EMPTY 与 SEM_FULL)用于环形队列的同步


SEM_EMPTY = 0,表示目前队列只有0个数据为空(本人倾向于记SEM_CURRENT=0,更方便记忆。)

当 SEM_FULL = 0 时,表示目前队列剩余0为满,则生产者进程阻塞。(本人倾向于记SEM_REST=0,更方便记忆)


网络编程之字节序转换API

ip字符串转换网络字节序:

1
2
int inet_aton(const char *cp, struct in_addr *inp);     [addr to network]
功能:将cp指向的IP字符串转成网络字节inp保存的地址中。

网络字节序转换IP字符串

1
2
3
4
5
6
7
char *inet_ntoa(struct in_addr in);   [network to addr]
功能:将IP网络字节序转换成IP字符串
参数:
@in IP网络字节序

返回值:
成功返回IP字符串首地址,失败返回NULL

主机字节序转换为网络字节序

1
2
3
4
5
short htons(short data);        [host  to network short ]
功能:将short类型的整数转成网络字节序
参数:
@data 序号转换的整数
返回值:得到的网络字节序

网络字节序转换为十进制数

1
2
3
4
5
6
7
8
9
10
11
12
13
int  atoi(const char *nptr)
功能:把ntpr 所指向的整数字符串转换成整数。
参数:
@ nptr 字符串
返回值:成功,返回转换后的整数
失败,返回0
注意:若是只有+,-和整数字符能转换,其他字符返回0

uint32_t ntohs(uint32_t netlong); [network to host short]
功能:把网络字节序转换为主机端口
参数:
@ netlong 网络字节序
返回值: 返回对应的主机端口

静态库与动态库

静态库

在与文件链接形成可执行文件后,会绑定在一起,所以优点也就是在执行的时候不需要加载,可以直接运行,缺点相同的就是重复的占用会导致内存开销过大
静态库在linux以.a结尾,在windows中以.lib结尾。

静态库的制作:

首先需要把file.c编译成file.o:
gcc -c file.c -o file.o
然后把.o文件生成静态库:

1
ar -rs file.a file.o

生成静态库之后我们需要把main.c与静态库链接起来生成可执行文件:
gcc -I<头文件路径> -L<库的路径> main.c -l<静态库的名字> -o <可执行文件名>
gcc 编译器默认搜索头文件与库文件的路径
/usr/include 为头文件默认路径
/usr/lib 与 /lib 为库的默认路径.
假如你已经把头文件,库拷到了默认路径那么就不需要加上上两个参数。


动态库
与静态库相比显然有着不同的特性,动态库加载速度偏慢,但在一般情况对内存的占用要比静态库更少。
在windows中以.dll文件结尾,十分常见,在linux中以.so文件结尾.
当可执行文件调用动态库中的函数时,则需要加载动态库到内存中
动态库的制作:

gcc -c file.c -o file.o

然后生成动态库
gcc -shared file.o -o file.so
链接的命令则和静态库的一样,然后我们如果只这样执行可执行文件是会报错的:

error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory

这是因为我们没有将动态库加载到内存中,默认动态库的位置是/usr/lib,如果我们的动态库在当下目录,我们可以
export LD_LIBRARY_PATH=.

linux文件io

踏入了阶段四

在 Linux 系统下,用于对文件操作的库函数叫做 文件 I/O
主要包括 open()/close()/read()/write() /lseek()相应的系统调用(准确说法是对系统调用的封装的库函数)