当前位置: 首页 > news >正文

网络编程2

TCP编程

scoket

create an endpoint for communicate

socket在内核区创建了一个文件对象,里面有发送缓冲区和接收缓冲区。

scoket(domain,type)各项参数含义:

  • domain 领域:AF_INET  ipv4协议
  • type 通信协议:SOCK_STREAM  有序,可靠,全双工(与AF_INET一起使用,选择的是TCP协议)

bind

bind a name to a socket

服务端是被动的,一定要bind才能被别人发现。客户端可以band,可以不bind。在TCP编程中,不推荐客户端bind,bind后ip和端口绑定,若客户端服务端都bind后,四元组确定,断开连接后,经历一段时间后才能重新建立连接。客户端不bind ,方便同时建立多条链接。

bind(sockfd,*addr,addrlen)

  • sockfd 填socket调用的返回值
  • addr 填网络地址在内存中的指针(填写的是公共类型)
  • addrlen 填网络地址在内存中的大小

注:bind 只能绑定本地ip地址,本地ip地址使用ifconfig查看

bind需要检错,一般情况下可能会出错

ifconfig

ens33 外网网卡 通信的其中一端在本机之外,走外网网卡

lo 本地环回设备 通信的双方都在本机之中,数据就不需要走外网网卡,直接内部通信即可。

端口号

16bit 0~65535

0~1023: 知名协议端口号

  • 80 http
  • 443 https
  • 22 ssh

最好是两万以内的端口号都别用,以免选到知名协议端口

 connect 

initiate a connection on a socet

connect(scoket,*addr,addrlen)

  • sockfd 填scoket的文件描述符
  • addr&addrlen 填服务端的 ip 和 port

排查网络故障的一般流程

  1. netstat -an 重点查看最后一列,查看出问题的网络状态
  2. 抓包:tcpdump抓包存到一个 *.cap文件:1- 切换到root用户 2- 
  3. 将 *.cap 文件拷贝到 windows(可用winscp), 用wireshark来阅读

listen

listen for connections on a socket

创建socket是一个主动的,只有listen()后才会成为被动的socket。

listen(scokfd,backlog):

  • sockfd 填写socket的文件描述符
  • backlog 写50就够用了

从通信scoket变成了拥有半连接队列和全连接队列的监听socket。

在listen之后,服务端调用listen,listen本身不会阻塞,也不会收发数据,listen切换了服务端状态。

当服务端调用完listen后,如果客户端connect,客户端会发起第一次握手,服务端进程收到第一次握手,操作系统内核负责将这次连接放入半连接队列,操作系统会回复第二次握手。客户端随后收到第二次握手,回复第三次握手,connect成功后,客户端已经进入ESTABLISHED状态。服务端随后收到第三次握手,操作系统内核负责将连接从半连接队列出队,移入全连接队列,服务端进入ESTABLISHED状态。

listen不处于三次连接的任何一次,时间极短,改变状态。

安全问题

伪造的客户端,只发第一次握手,不发第三次握手(SYN flooding攻击)。被拿到操作系统权限的机器称为肉鸡,可以使用大量肉鸡进行SYN flooding 攻击服务端(被称为DDOS攻击)。

accept

accept a connection on a socket

accept()

  • sockfd 监听sockfd的fd
  • addr&addrlsn 传入传出 可以都填NULL,只取出连接不获取对面的ip和port,如果想获取对面的ip和port,addrlen指向的值为sizeof(addrlen)。

返回值int ,是新的文件描述符。

检查、监听socket里面的全连接队列

  • 若无连接,进程阻塞
  • 若有连接,按照先进先出的方式取出连接,并可以获取对面的 ip 和 port

在操作系统的内核视角里面,accept 的本质和read是一样的。类比全连接队列和管道接收缓冲区。

当收到某客户端连接请求,会调用accept时候创建一个通信socket(有一个发送缓冲区和一个接收缓冲区),并分配一个文件描述符。可以类比于使用了两个单工管道实现全双工通信。

若文件描述符超出大小,可使用ulimit -a更改open file(1024)大小到足够大。

send

send(sockfd,*buf,len,flags)

  • sockfd :socket文件描述符
  • buf : 用户缓冲区数据。
  • len : 使用strlen() 得到数据实际长度
  • flags :  一般填0就可以

send是一种特殊的write,send直接完成的事情是拷贝,将用户态的 buf 数据拷贝到内核发送缓冲区,数据到内核缓冲区后,由内核协议栈真正的收发数据。发送时,数据超出mtu,内核协议栈进行切分,用户不需要考虑收发数据。使用一次send可能会分几次发送到网络。

发送缓冲区为空的时候,send不会阻塞。

recv

recv(sockfd,*buf,len,flags)

  • sockfd : socket文件描述符
  • buf : 用户缓冲区,内存可以适当多申请一些,一个栈帧大小大概为10M,根本用不完。
  • len : 使用sizeof() 限定缓冲区上限值。
  • flags 一般填0

recv是一种特殊的read,recv直接完成的事情是拷贝,将内核接收缓冲区的内容拷贝到用户态的buf中,而接收数据时由内核协议栈完成。

接收缓冲区为空的时候,recv会阻塞。

send和recv对于用户的意义

在应用层,永辉不需要考虑数据如何收发(乱序、丢包等),用户只需要管把数据扔到缓冲区即可。用户的视角中完全可以把建立好的连接看成两根单向管道即可。

可以使用write、read取代send、recv。反过来不行,send、recv只能操作通信socket,不能操作磁盘文件、设备文件、管道文件。

相关文章:

  • STM32H7系列USART驱动区别解析 stm32h7xx_hal_usart.c与stm32h7xx_ll_usart.c的区别?
  • 湖北理元理律师事务所债务优化服务中的“四维平衡“之道
  • 离轴全息记录与再现
  • 【iOS】 GCD小结
  • Qt 改变窗口显示透明度 + 光标显示形状的属性(4)
  • Redis集群的脑裂问题
  • Pyhton_25_5_26
  • 海外社媒矩阵运营:IP代理配置与区域突破实战策略
  • AI工具使用的最佳实践,如何通过AI工具提高创作与工作效率
  • 涨薪技术|0到1学会性能测试第83课-Windows Sockets录制
  • C++中使用类的继承机制来定义和实现基类与派生类
  • OpenHarmony平台驱动使用(二),CLOCK
  • 编程日志5.21
  • Windows计算机管理:定时调用指定的可执行程序(.exe)
  • Agilent安捷伦Cary3500 UV vis光谱仪Cary60分光光度计Cary1003004000500060007000 UV visible
  • HMI仿真报错
  • 布局泰国遇网络难题?中泰跨境网络组网专线成破局关键
  • Java集合操作常见错误及规避方法
  • 【SQL server】 SQL子查询:与连接的区别、类型划分、相关与非相关子查询对比
  • Point-wise vs Pair-wise vs List-wise 简述
  • win2003 建设网站/投广告的平台有哪些
  • 峰峰信息港邯郸信息港/惠州seo推广优化
  • 凡科的模板做网站/谷歌google下载
  • 好的买手表网站/百度推广获客
  • 可以随意做配搭的网站/市场推广是做什么的
  • 盐城专业做网站的公司哪家好/友情链接交换源码