【Linux】Socket编程TCP

TCP socket API 详解

回顾程序中用到的socket API函数:

socket()

  • 对于IPv4,family参数指定为AF_INET
  • 对于TCP协议,type参数指定为SOCK_STREAM,表示面向流的传输协议

bind()

  • 服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端 口号后就可以向服务器发起连接
  • 服务器需要调用bind绑定一个固定的网络地址和端口号
  • bind()成功返回0,失败返回-1
  • bind()的作用是将参数sockfd和myaddr绑定在一起,使sockfd这个用于网络通讯的文件描述符监听myaddr所描述的地址和端口号
  • 因为struct sockaddr *是一个通用指针类型,myaddr参数实际上可以接受多种协议的sockaddr结构体,而它们的长度各不相同,所以需要第三个参数addrlen指定结构体的长度
  • 多线程 TCPServer.hpp

listen()

  • listen()声明sockfd处于监听状态,并且最多允许有backlog个客户端处于连接等待状态,如果接收 到更多的连接请求就忽略,设置不会太大(一般是5)
  • listen()成功返回0,失败返回-1

accept()

  • 如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来
  • addr是一个传出参数,accept()返回时传出客户端的地址和端口号
  • 如果给addr参数传NULL,表示不关心客户端的地址
  • addrlen参数是一个传入传出参数(value-result argument),传入的是调用者提供的,缓冲区addr 的c长度以避免缓冲区溢出问题,传出的是客⼾端地址结构体的实际长度

connect()

  • 客户端需要调用connect()连接服务器
  • connect和bind的参数形式一致,区别在于bind的参数是自己的地址,而connect的参数是对放的地址

1. V1 - Echo Server

思路:

根据实现发现由于:

  • 当启动一个客户端后再启动一个客户端,尝试连接服务器,发现第二个客户端不能正确的和服务器进行通信
  • 分析原因,是因为我们 accecpt 了一个请求之后,就在一直 while 循环尝试 read ,没有继续调用accecpt ,导致不能接受新的请求
  • 所所以单进程版本的TCP ,只能处理一个连接,这是不科学的

2. V2 - Echo Server多进程版本

思路:

代码实现:

TCP实现客户端echo 单进程+多进程版

3. V3 - Echo Server多线程版本

思路:

代码:

TCP多线程版本代码

4. V3-1 - 多线程远程命令执行

Command.hpp:命令类,⽤来执行命令,并获取结果

代码:

多线程远程命令执行

5. V4 - Echo Server 线程池版本

引入系统部分的线程池,进行简单的业务处理

代码:

线程池版本实现

相关推荐
企鹅侠客31 分钟前
Linux CPU 负载平均值(Load Average)详解:从原理到实践
linux·运维·服务器·服务器负载
吃一碗粉只付一碗钱1 小时前
10-令牌里的用户主键不要明文
服务器·数据库·sql·sqlserver·c#
lazy H1 小时前
【计算机网络】第 13 篇:NAT 和端口映射是什么?为什么本地服务外网访问不了?
java·网络·网络协议·学习·计算机网络·408
Linux运维技术栈1 小时前
WAF部署在防火墙后面,获取不到真实IP怎么办?
服务器·网络·tcp/ip·安全·防火墙·waf
广目软件1 小时前
HA分布式架构采集节点变更操作手册20261029
运维·服务器·ansible·zabbix·prometheus
米优1 小时前
linux下获取崩溃程序的core文件
linux·运维·服务器
xie881018022 小时前
正则里的点号不匹配换行:多行模式的开关
运维·服务器·测试工具
低慢小uav2 小时前
(已解决)Zynq芯片lwip协议栈,使用tcp作为服务器Service,接收大量数据时,长度接收正常,接收对数据校验,校验和异常分析
网络协议·tcp/ip·fpga开发
垆边人似月.2 小时前
RDMA项目踩坑(一):为什么最后一块数据必须使用实际长度?
网络·c/c++·rdma·高性能io·tcp与rdma
YH_Analytics2 小时前
2026 高压 E-House 市场深度分析报告市场格局
网络·数据库