目录
1.socket函数
2.地址转换函数
1.字符串转in_addr的函数:编辑
2.in_addr转字符串的函数:编辑
1.关于inet_ntoa函数
3.listen函数
4.简单的Server模型
1.初步模型
1.sock函数和accept函数返回值的sockfd的区别
2.运行结果和127.0.0.1的意义
2.单进程模板
3.多进程模板
1.让孙子执行代码,子进程退出
2.让父进程接受到子进程退出的信号是选择忽略
4.多线程模板
5.线程池模板
1.建议先看一下udp协议:udp协议下的socket函数_udp socket函数-CSDN博客
1.socket函数
其实从上面两个区别,就能看出socket下的type使用的区别了,tcp用的是SOCK_STREM.
2.地址转换函数
1.字符串转in_addr的函数:
2.in_addr转字符串的函数:
1.关于inet_ntoa函数
inet_ntoa这个函数返回了一个char*,很显然是这个函数自己在内部给我们申请了一块内存空间,那是否需要我们自己手动释放呢?
man手册上说,inet_ntoa函数,是把这个返回值结果放到了静态存储区,这个时候就不需要我们手动释放了。但是问题来了,如果我们调用多次这个函数,会有什么样的效果呢?
运行结果:
所以我们下次应避免使用这个函数。
但是在多线程的情况下运行是没有这个情况的,理论上线程是共享内存地址空间的,那么开辟的静态空间也是重复的!但是,(我承认下面这段是copy的,哈哈哈哈)
inet_ntoa() 函数的行为依赖于实现它的库和编译器环境。在标准 C 库(如 glibc)的早期版本中,inet_ntoa() 确实返回指向内部静态缓冲区的指针,这意味着多次调用 inet_ntoa() 可能会覆盖先前的结果,特别是在多线程环境中。
然而,现代的 C 库(如 glibc 2.24 及以上版本)和编译器环境(如 GCC 和 Clang)通常会对 inet_ntoa() 进行优化,使其在多线程环境中更加安全。这些优化通常涉及使用线程局部存储(TLS)来为每个线程分配独立的缓冲区,或者在每次调用时分配一个新的栈上缓冲区。
3.listen函数
Tcp是面向连接的,服务器一般是比较“被动的”,服务器一直处于一种:一直在等待连接到来的状态。
backlog不要设置的太大,具体作用后面再讲。
4.简单的Server模型
1.初步模型
main.cc
UdpServer.hpp
1.sock函数和accept函数返回值的sockfd的区别
sock函数和accept函数的返回值都是sockfd,那么他们之间有什么区别呢?你可以把sock函数返回的sockfd当做招揽客户进入餐厅的员工,而accept返回的sockfd是具体服务进来客户的员工!
2.运行结果和127.0.0.1的意义
可以通过右边telnet来连接主机,而127.0.0.1是主机回环地址,
更详细的请看这篇博主写的:彻底明白ip地址,区分localhost、127.0.0.1和0.0.0.0 - 简书
2.单进程模板
缺点就是每次只能有一个客户进去,这样肯定不行的。
3.多进程模板
其实稍微仔细观察,就发现他其实接受不了多个客户,因为父进程需要等待还没有退出的子进程,不然会僵尸。所以有些人说那就轮询啊,但是那又要存储子进程的pid值,但是后面回收还是存在问题,还要数组存储退掉的子进程和没有退掉的子进程。
1.让孙子执行代码,子进程退出
2.让父进程接受到子进程退出的信号是选择忽略
我在这篇博客的最后面提到过。
linux信号的概念-CSDN博客
但是进程的创建是很大的,所以我们需要用线程来执行方案。
4.多线程模板
5.线程池模板
thread_pool.hpp
Linux线程池-CSDN博客
Task.hpp