Linux网络编程02

这篇具有很好参考价值的文章主要介绍了Linux网络编程02。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

UDP协议

UDP协议处于传输层,是不可靠谱、无连接、消息有边界的协议
TCP类似于管道,UDP类似于队列

UDP头部
传输层头部都不需要IP地址,都只需要端口号
Linux网络编程02,Linux,linux,网络,c语言

Berkeley Socket(库)

Berkeley Scoket 库已经完成了传输层之下的内容,我们只需要再应用层调用下面提供的服务接口即可

Socket :套接字,建立连接时使用

地址:链路层使用MAC地址、网络层使用IP地址、传输层使用端口号
应用层的地址:IP地址加上端口号

IPv4的地址格式
Linux网络编程02,Linux,linux,网络,c语言
sin_family:地址的类型AF_INET代表IPv4
sin_port:端口号(使用网络字节序)16Byte(2字节)
sin_addr:IP地址(使用网络字节序)32Byte(4字节)

网络字节序
大端法存储数据被称为网络字节序
大小端都可以存储数据的为主机字节序
Linux网络编程02,Linux,linux,网络,c语言
数据如果要从主机到网络,那么我们就要将小端数据变成大端数据

Linux网络编程02,Linux,linux,网络,c语言
h host主机
n net网络
s short 2B 16bit
l int 4B 32bit

大小端转换
我们要用printf()就使用小端;如果我们使用sockaddr就使用大端
Linux网络编程02,Linux,linux,网络,c语言

Linux网络编程02,Linux,linux,网络,c语言

const char *cp:点分十进制
struct in_addr *inp:存储结果的地址
inet_aton(const char * cp ,struct in_addr * np):点分十进制—>32位大端整数,结果作为参数
inet_addr:点分十进制—>32位大端整数,结果作为返回值

char *inet_ntoa:把32位大端整数转换为字符串

IP地址实现大小端转换
Linux网络编程02,Linux,linux,网络,c语言

IP地址以及端口实现大小端转换
Linux网络编程02,Linux,linux,网络,c语言

可以使用sudo cat /etc/hosts查看本地存在的域名映射

从代码中获取域名对应的IP地址
Linux网络编程02,Linux,linux,网络,c语言
底层使用了DNS服务器,断网的时候会报错,这个函数出错了不能用perror,报错返回空指针
可以根据这个函数获取主机信息
Linux网络编程02,Linux,linux,网络,c语言

使用gethostbyname获取远程目标主机的信息
Linux网络编程02,Linux,linux,网络,c语言

可以将IPv4或者IPv6转换位字符串
Linux网络编程02,Linux,linux,网络,c语言

基于TCP的网络通信
网络的用法和文件是一样的
Linux网络编程02,Linux,linux,网络,c语言

socket(系统调用)

创建一个用于网络传输的文件对象
Linux网络编程02,Linux,linux,网络,c语言

domain:指的是你所使用的领域,一般使用AF_INET表示IPv4
Linux网络编程02,Linux,linux,网络,c语言
type:
Linux网络编程02,Linux,linux,网络,c语言
SOCK_STREAM:TCP协议
SOCK_DGRAM:UDP协议
protocol:填0表示自动获取

connect
建立连接,发送第一次握手

Linux网络编程02,Linux,linux,网络,c语言
sockfd:填的值是socket的返回值
addr 和addrlen描述目标地址

Linux上使用抓包操作查看自己发送的数据包
tcpdump -i 网卡名称 port 端口号
Linux网络编程02,Linux,linux,网络,c语言

tcp的标志
根据四元组<源IP,源端口号,目的IP,目的端口>来区分两条不同的TCP连接,只要四元组中有一个不一样那就是不同的TCP连接

服务端的IP和端口一般是固定的—>这不影响并发连接数量的上限

bind(服务端)
让服务端端绑定一个IP:port给socket ,以便于客户端每次都可以固定的和同一个端口连接服务端

Linux网络编程02,Linux,linux,网络,c语言
绑定端口之后客户端还不能连接服务端,还需要让服务端调用listen系统调用

listen(服务端调用)
listen是说明让socket当作服务端来使用
服务端调用listen之后客户端才能connect
listen会把socket文件对象清空,会重新组织成两个数据结构,一个是半连接队列,一个是全连接队列
当服务端调用listen,接收到客户端的connect请求,服务端会像客户端发回ACK应答,此时这个客户端就会进入如半连接队列里面,当客户端完成了三次握手的最后一个ACK是服务端就会把这个连接放入连接队列里面

Linux网络编程02,Linux,linux,网络,c语言
backlog:半连接队列的长度

DDOS攻击
SYN flood 泛洪
客户端你只对服务器只发送第一次握手,但是不发生送第三次握手,方客户端越来越多的时候服务器端的半连接队列就会被充满,以至于服务器无法在继续连接真难正需要连接的客户端
如何防御DDOS攻击?
(1)增发半连接队列(不可取)
(2)使用SYN cookies

accept
上面我们已经了解到我们可以使用socket为客户端创建一个用于网络连接的文件,对于服务端首先会使用bind为客户端绑定固定端口,然后再利用listen改造客户端的socket文件对象,建立连接之后便会把客户端建立的连接放入全连接队列。
接下来调用accept从全连接队列取出一个连接,根据这个连接创建一个已链接socket
因此就会有两个文件描述符一个是socketFd(用于建立连接),一个是netFd(用于发送数据)
accept的本质是一个read,如果全连接队列为空,accept就会阻塞,当全连接队列不为空就会停止阻塞

Linux网络编程02,Linux,linux,网络,c语言
sockfd:listen 的 fd
addr:addr填本地地址,如果填了本地地址就可以获取对端地址,如果不想获取对端地址就填NULL
addrlen:先申请一个socklen_t的变量,再取地址传递,因为他是一个传入传出参数,并且socklen_t的长度不能嫩能够填0,要填addr的长度

读写网络缓冲区
write/read 可以用于客户端的socket以及服务端端的已连接socket,不可以用于listensocket
send和recv只能操作socket
write和read可以操作文件和socket以及管道等

send和write
Linux网络编程02,Linux,linux,网络,c语言
flages:控制send的行为,如果为0,不做任何行为
在对socket操作时 send(… , 0)和write是等价的
send/write不是往网络中发数据,其本质是拷贝数据到SND(发送)缓冲区,发不发送由内核协议栈决定是否发向网络

read和recv
Linux网络编程02,Linux,linux,网络,c语言
read/recv是拷贝数据从RCV缓冲区到用户空间,网络中如果没有数据就会发生阻塞

使用socket实现网络连接

Linux网络编程02,Linux,linux,网络,c语言
Linux网络编程02,Linux,linux,网络,c语言

如何使接收方和发送方知道相同的信息,就需要在应用层制定协议

利用socket实现即时聊天

基本 上和管道时一样的,socket的R,W的fd是同一个
使用IO多路复用来防止stdin阻塞
Linux网络编程02,Linux,linux,网络,c语言

Linux网络编程02,Linux,linux,网络,c语言

TIME_WAIT

主动关闭方在四次挥手之后会进入TIME_WAIT状态
服务端如果主动关闭,会进入TIME_WAIT(固定60S),服务端在time_wait状态,不允许bind同样的IP端口,避免在这个时间之内他们两方在建立新的连接,但是旧连接的数据可能就会在新连接里传输
但是每次客户端发起新的连接都是从不同的端口进行发出,因此每次发起连接的四元组都是不一样的,因此我们没有必要让服务端进入TIME_WAIT

让服务端你无视TIME_WAIT
修改socket的属性(在bind之前修改)

使用setsockopt修改socket的属性
Linux网络编程02,Linux,linux,网络,c语言

sockfd:listen socket,监听描述符 level
:直接填SOL_SOCKET,表示修改的是socket这一层(传输层) optname:要修改哪个属性
Linux网络编程02,Linux,linux,网络,c语言

optval:要改成什么样 optlen:属性的长度

Linux网络编程02,Linux,linux,网络,c语言
服务端不是屏蔽TIME_WAIT而只是忽略TIME_WAIT

实现断线重连

服务端使用select监听sockfd—>读事件,如果都就绪,说明调用accept不会阻塞

  #include <43func.h>
   //服务端
   int main(int argc,char * argv[]) {
       ARGS_CHECK(argc,3);
       int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建你IPv4的TCP连接
       ERROR_CHECK(sockfd,-1,"socket");
       int optval = 1;
       int ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(int));
       ERROR_CHECK(ret,-1,"setsockopt");
      struct sockaddr_in addr;
      addr.sin_family = AF_INET;
      addr.sin_port = htons(atoi(argv[2]));
      addr.sin_addr.s_addr = inet_addr(argv[1]);
      ret = bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
      ERROR_CHECK(ret,-1,"bind");
      ret = listen(sockfd,10);//更改server端socket的结构,更改半连接队列长度为10
      ERROR_CHECK(ret,-1,"listen");
      //accept要放在select后面
      //去使用时确保从标准输入中输入数据在客户端建立连接之后
      //accept之后创建新的netfd,这个netfd加入监听--->分离监听和就绪
      //客户端如果断开连接以后,服务端不要退出,要取消监听netfd
      fd_set rdset;//保存就绪的fd
      fd_set monitorSet;//使用一个单独的监听集合
      FD_ZERO(&monitorSet);//初始化rdset
      FD_SET(STDIN_FILENO,&monitorSet);//将文件输入流,添加到监听队列.防止阻塞
      char buf[4096] = {0};
      int netfd = -1;
      while(1) {
          memcpy(&rdset,&monitorSet,sizeof(fd_set));//初始化数组
          select(20,&rdset,NULL,NULL,NULL);//开启监听
          if(FD_ISSET(STDIN_FILENO,&rdset)){
              bzero(buf,sizeof(buf));//清空数组
              ret = read(STDIN_FILENO,buf,sizeof(buf));//读取输入流数据
              if(ret == 0) {
                  send(netfd,"nishigehaoren",13,0);
                  break;
              }
              send(netfd,buf,strlen(buf),0);//向网络文件中写入数据
          }
          if(FD_ISSET(sockfd,&rdset)){
              netfd = accept(sockfd,NULL,NULL);//创建socket文件对象
              ERROR_CHECK(netfd,-1,"accept");
              FD_SET(netfd,&monitorSet);//将netfd加入监听集合
              puts("new connect is accepted!\n");
          }
          if(FD_ISSET(netfd,&rdset)) {
              bzero(buf,sizeof(buf));//清空buf
              ret = read(netfd,buf,sizeof(buf));//读取网络文件中的数据
              if(ret == 0) {
                  puts("bye bye");
                  FD_CLR(netfd,&monitorSet);//将netfd取消监听
                  close(netfd);
                  netfd = -1;
                  continue;
              }
              puts(buf);
          }
      }
      close(sockfd);
      close(netfd);
  }

Linux网络编程02,Linux,linux,网络,c语言

实现群聊
Linux网络编程02,Linux,linux,网络,c语言
Linux网络编程02,Linux,linux,网络,c语言

UDP实现聊天
Linux网络编程02,Linux,linux,网络,c语言
bind:固定服务端的IP:port
sendto:客户端先sendto

UPD中socket的用法
client
Linux网络编程02,Linux,linux,网络,c语言
server
Linux网络编程02,Linux,linux,网络,c语言文章来源地址https://www.toymoban.com/news/detail-715428.html

到了这里,关于Linux网络编程02的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux系统应用编程(五)Linux网络编程(上篇)

    1.两个网络模型和常见协议 (1)OSI七层模型(物数网传会表应) 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层(自下到上) (2)TCP/IP四层模型(网网传应) 网络接口层(链路层)、网络层、传输层、应用层 (3)常见网络协议所属层 2.字节序 (1)两种

    2023年04月25日
    浏览(36)
  • 【Linux网络编程】网络编程套接字二

    喜欢的点赞,收藏,关注一下把! TCP和UDP在编程接口上是非常像的,前面我们说过TCP是面向连接的,UDP我们上篇博客也写过了,我们发现UDP服务端客户端写好启动直接就发消息了没有建立连接。TCP是建立连接的,注定在写的时候肯定有写不一样的地方。具体怎么不一样,我们

    2024年04月15日
    浏览(61)
  • Linux网络编程——UDP编程

    1、UDP通信协议,服务器端和客户端无需建立连接,只需要知道对方套接字的地址信息就可以发送数据 2、UDP通信流程图: 功能:创建套接字并返回套接字描述符 功能:将套接字与IP地址和端口号绑定 功能:发送数据 功能:接收数据 功能:关闭套接字 1、代码功能:两个进程

    2023年04月19日
    浏览(43)
  • Linux网络编程:网络基础

    文章目录: 一:协议   二:网络应用设计模式_BS模式和CS模式 三:网络分层模型(OSI七层 TCP/IP四层) 四:通信过程 五:协议格式  1.数据包封装 2.以太网帧格式和ARP数据报格式  3.IP段格式  4.UDP数据报格式 5.TCP数据报格式 六:TCP协议 1.TCP通信时序(面向连接的可靠数据通

    2024年02月12日
    浏览(81)
  • linux【网络编程】之网络基础

    “协议” 是一种约定 软件设计方面的优势—低耦合 分层依据:功能比较集中,耦合度较高的模块—高内聚 每一层都要解决特定的问题 每一层都有自己匹配的协议,每一层协议都解决自己的问题 OSI(Open System Interconnection,开放系统互连)七层网络模型称为开放式系统互联参

    2024年02月04日
    浏览(53)
  • 【Linux网络编程】网络基础一

    从今天开始我们将要从系统横跨到网络的学习了,因此有些书我们就可以读起来了。 操作系统 原理: 《操作系统精髓与设计原理》、《现代操作系统》 Linux原理方面的书 : 《Linux内核设计与实现》–陈莉君、《深入理解Linux内核》(选读–不作为重点) Linux编程方面的书: 《

    2024年04月15日
    浏览(58)
  • Linux网络编程 网络基础知识

    目录 1.网络的历史和协议的分成 2.网络互联促成了TCP/IP协议的产生 3.网络的体系结构 4.TCP/IP协议族体系 5.网络各层的协议解释 6.网络的封包和拆包 7.网络预备知识      Internet-\\\"冷战\\\"的产物 1957年十月和十一月,前苏联先后欧两颗”Spuinik”卫星上天 1958年美国总统艾森豪威尔向

    2024年02月10日
    浏览(44)
  • 【网络编程】Linux网络编程基础与实战第三弹——网络名词术语

    数据包从源地址到目的地址所经过的路径,由一系列路由节点组成。 某个路由节点为数据包选择投递方向的选路过程。 路由器工作原理 路由器是连接因特网中各局域网、广域网的设备,它会根据信道的情况自动选择和设定路由,以最佳路径,按前后顺序发送信号的设备。

    2024年02月08日
    浏览(44)
  • Linux网络编程

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇

    2024年01月24日
    浏览(37)
  • linux 网络编程

    网络通信手段的一种,我们在之前学了进程间通信,包括管道、消息队列、共享内存、信号和信号量,这些通信方式有一个共同的特点,就是他们都是在依赖Linux内核在单机上进行进程的通信,而面对多机之间的通信,这些手段就远远不够了。所以我们引入网络,利用网络来

    2024年02月12日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包