Linux 网络编程 + 笔记

协议:一组规则

分层模型结构:

  • OSI七层模型:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
  • TCP/IP 4层模型:链路层/网络接口层、网络层、传输层、应用层
    • 应用层:http、ftp、nfs、ssh、telnet、
    • 传输层:TCP、UDP
    • 网络层:IP、ICMP、IGMP
    • 链路层:以太网帧协议、ARP

C/S模型和B/S模型

  • C/S模型:client-server
  • B/S模型:browser-server

网络传输流程:

  • 数据没有封装之前,是不能在网络中传递
  • 数据-》应用层-》传输层-》网络层-》链路层  --- 网络环境

以太网帧协议:

  • ARP协议:根据IP地址获取mac地址
  • 以太网帧协议:根据mac地址,完成数据包传输

IP协议:

  • 版本: IPv4、IPv6  -- 4位
  • TTL:time to live (设置数据包在路由节点中的跳转上限,每经过一个路由节点,该值-1, 减为0的路由,有义务将该数据包丢弃)
  • 源IP:32位 -- 4字节 
192.168.1.108 --- 点分十进制 IP地址(string)
  • 目的IP:32位--- 4字节

IP地址:可以在网络环境中,唯一标识一台主机

端口号:可以进行网络通信的一台主机上,唯一标识一个进程

IP地址+端口号:可以在网络环境中,唯一标识一个进程

UDP协议16位:源端口号     2^16 = 6553616位:目的端口号TCP协议16位:源端口号     2^16 = 6553616位:目的端口号32序号32确认序号6个标志位16位窗口大小       2^16 = 65536

网络套接字:socket

  • 一个文件描述符指向一个套接字(该套接字内部由内核借助两个缓冲区实现)
  • 在通信过程中,套接字一定是成对出现的

网络字节序:

  • 小端法:(pc本地存储)    高位存高地址,低位存低地址            int a = 0x12345678
  • 大端法:(网络存储)        高位存低地址,低位存高地址         
    htonl --> 本地--》网络 (IP)			192.168.1.11 --> string --> atoi --> int --> htonl --> 网络字节序htons --> 本地--》网络 (port)ntohl --> 网络--》 本地(IP)ntohs --> 网络--》 本地(Port)

 注意:htonl --> 本地 --> 网络(IP)

192.168.1.11 --> string --> atoi --> int --> htonl --> 网络字节序

IP地址转换函数

  1. inet_pton
  2. inet_ntop
  • 本地字节序(string IP) ---> 网络字节序 
// 本地字节序(string IP) ---> 网络字节序
int inet_pton(int af, const char *src, void *dst);af: AF_INET,AF_INET6src:传入,IP地址(点分十进制)dst:传出转换后的 网络字节序的 IP地址返回值:成功:   1异常:   0,说明src指向的不是一个有效的ip地址失败:  -1
NAMEinet_pton - convert IPv4 and IPv6 addresses from text to binary formSYNOPSIS#include <arpa/inet.h>int inet_pton(int af, const char *src, void *dst);DESCRIPTIONThis  function converts the character string src into a network addressstructure in the af address family, then  copies  the  network  addressstructure  to dst.  The af argument must be either AF_INET or AF_INET6.dst is written in network byte order.
  • 网络字节序  ---> 本地字节序(string IP) 
// 网络字节序  ---> 本地字节序(string IP)
const char *inet_ntop(int af, const void *src,char *dst, socklen_t size);af: AF_INET,AF_INET6src: 网络字节序IP地址dst: 本地字节序(string IP)size: dst的大小返回值: 成功: dst失败: NULL
NAMEinet_ntop - convert IPv4 and IPv6 addresses from binary to text formSYNOPSIS#include <arpa/inet.h>const char *inet_ntop(int af, const void *src,char *dst, socklen_t size);DESCRIPTIONThis  function  converts  the  network  address  structure src in the afaddress family into a character string.  The resulting string is  copiedto  the buffer pointed to by dst, which must be a non-null pointer.  Thecaller specifies the number of bytes available in  this  buffer  in  theargument size.
  • sockaddr地址结构: IP + Port  --> 在网络环境中唯一标识一个进程 
sockaddr地址结构: IP + Port  --> 在网络环境中唯一标识一个进程struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(8080);
#if 0int dst;inet_pton(AF_INET,"192.168.1.100",(void*)dst);   addr.sin_addr.s_addr = dst;
#else// 取出系统中有效的任意IP地址(二进制类型)addr.sin_addr.s_addr =  htonl(INADDR_ANY);bind(fd,(struct sockaddr*)&addr,sizeof(addr));

  • socket函数,创建一个套接字
socket函数#include <sys/socket.h>// 创建一个套接字int socket(int domain, int type, int protocol);domain: AF_INET,AF_INET6type: SOCK_STREAM,SOCK_DGRAMprotocol: 0返回值:成功: 新套接字所对应文件描述符失败: -1 errno
NAMEsocket - create an endpoint for communicationSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int socket(int domain, int type, int protocol);DESCRIPTIONsocket()  creates  an  endpoint  for  communication  and  returns a filedescriptor that refers to that endpoint.  The file  descriptor  returnedby  a  successful  call  will be the lowest-numbered file descriptor notcurrently open for the process.
  • bind函数 
#include <arpa/inet.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);sockfd: socket 函数返回值struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(8080);addr.sin_addr.s_addr = htonl(INADDR_ANY);addr:传入参数(struct sockaddr*)&addraddrlen:sizeof(addr) 地址结构的大小返回值:成功: 0失败: -1 errno
NAMEbind - bind a name to a socketSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);DESCRIPTIONWhen  a  socket  is  created  with  socket(2), it exists in a name space(address family) but has no address assigned to it.  bind() assigns  theaddress specified by addr to the socket referred to by the file descrip‐tor sockfd.  addrlen specifies the size, in bytes, of the address struc‐ture  pointed  to  by  addr.   Traditionally,  this  operation is called“assigning a name to a socket”.It is normally necessary to assign a local address using bind() before aSOCK_STREAM socket may receive connections (see accept(2)).
  • listen函数,设置同时与服务器建立连接的上限数(同时进行3次握手的客户端数量)
// 设置同时与服务器建立连接的上限数(同时进行3次握手的客户端数量)
int listen(int sockfd, int backlog);sockfd: socket 函数返回值backlog: 上限数值,最大值为128返回值:成功: 0失败: -1 errno
NAMElisten - listen for connections on a socketSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int listen(int sockfd, int backlog);DESCRIPTIONlisten()  marks  the  socket  referred to by sockfd as a passive socket,that is, as a socket that will be used  to  accept  incoming  connectionrequests using accept(2).The sockfd argument is a file descriptor that refers to a socket of typeSOCK_STREAM or SOCK_SEQPACKET.The backlog argument defines the maximum length to which  the  queue  ofpending  connections  for  sockfd  may  grow.   If  a connection requestarrives when the queue is full, the client may receive an error with  anindication  of  ECONNREFUSED  or,  if  the  underlying protocol supportsretransmission, the request may be ignored so that a later reattempt  atconnection succeeds.
  • accept函数,阻塞等待客户端建立连接,成功的话,返回一个与客户端成功连接的socket文件描述符
// 阻塞等待客户端建立连接,成功的话,返回一个与客户端成功连接的socket文件描述符
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);sockfd:socket 函数返回值addr:传出参数,成功与服务器建立连接的那个客户端的地址结构(IP+port)socklen_t client_addr_len = sizeof(addr);addrlen:传入传出  &client_addr_len入:addr的大小  出:客户端addr实际大小返回值:成功:能与客户端进行数据通信的 socket 对应的文件描述失败:-1,errno
NAMEaccept, accept4 - accept a connection on a socketSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);#define _GNU_SOURCE             /* See feature_test_macros(7) */#include <sys/socket.h>int accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags);DESCRIPTIONThe  accept()  system  call is used with connection-based socket types (SOCK_STREAM, SOCK_SEQPACKET).  It extractsthe first connection request on the queue of pending connections for the listening socket, sockfd, creates  a  newconnected  socket, and returns a new file descriptor referring to that socket.  The newly created socket is not inthe listening state.  The original socket sockfd is unaffected by this call.
  • connect函数
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);sockfd: socket 函数返回值struct sockaddr_in server_addr; // 服务器地址结构server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080);// 跟服务器bind时设定的 port 完全一致。inet_pton(AF_INET, "服务器IP地址", &server_addr.sin_addr.s_addr);addr:传入参数,服务器的地址结构addrlen:服务器的地址结构的大小返回值:成功: 0失败: -1,errno如果不使用bind绑定客户端地址结构,采用"隐式绑定".
NAMEconnect - initiate a connection on a socketSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);DESCRIPTIONThe  connect()  system  call connects the socket referred to by the filedescriptor sockfd to the address specified by addr.  The  addrlen  argu‐ment  specifies  the size of addr.  The format of the address in addr isdetermined by the address space of the socket sockfd; see socket(2)  forfurther details.If  the socket sockfd is of type SOCK_DGRAM, then addr is the address towhich datagrams are sent by default, and the  only  address  from  whichdatagrams  are  received.   If  the  socket  is  of  type SOCK_STREAM orSOCK_SEQPACKET, this call attempts to make a connection  to  the  socketthat is bound to the address specified by addr.Generally,  connection-based protocol sockets may successfully connect()only once; connectionless protocol sockets may  use  connect()  multipletimes  to change their association.  Connectionless sockets may dissolvethe association by connecting to an address with the sa_family member ofsockaddr set to AF_UNSPEC (supported on Linux since kernel 2.2).

TCP 通信流程分析: 

TCP 通信流程分析:Server:1.socket()      创建socket2.bind()        绑定服务器地址结构3.listen()      设置同时与服务器建立连接的上限数(监听上限)4.accept()      阻塞监听客户端连接5.read(fd)      读socket获取客户端数据6.小 -- 大写     toupper()7.write(fd)     8.close()Client:1.socket()       创建socket2.connect()      与服务器建立连接3.write()        写数据到socket4.read()         读转换后的数据5.显示读取结果6.close()
  • server.c
#include <arpa/inet.h>  
#include <unistd.h>  
#include <pthread.h>#include <errno.h> 
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  #include <ctype.h>  
#include <sys/socket.h>  #define SERVER_PORT 9527void sysErr(const char *msg) {perror(msg);exit(1);
}int main(int argc, char *argv[]) {int lfd = socket(AF_INET, SOCK_STREAM, 0);if (lfd == -1) sysErr("socket error");struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//给服务器socket绑定地址结构int ret = bind(lfd,(struct sockaddr*)&server_addr,sizeof(server_addr));if(ret == -1) sysErr("bind error");// 设置监听上限  ret = listen(lfd,128);if(ret == -1) sysErr("listen error");struct sockaddr_in client_addr;socklen_t client_addr_len = sizeof(client_addr);//  获取客户端地址结构大小// 阻塞等待客户端连接请求 int cfd = accept(lfd,(struct sockaddr*)&client_addr,&client_addr_len);if(cfd == -1) sysErr("accept error");// 根据accept传出参数,获取客户端 ip 和 port  char client_IP[1024];printf("client ip:%s port:%d\n",inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,client_IP,sizeof(client_IP)),ntohs(client_addr.sin_port));char buf[BUFSIZ];while(1) {ret = read(cfd,buf,sizeof(buf));write(STDOUT_FILENO,buf,ret);  // 写到屏幕查看// 转换为大写for(int i=0;i<ret;++i) {buf[i] = toupper(buf[i]); // 小写 -- 大写  }write(cfd,buf,ret);           // 将大写,写回给客户端}close(lfd);close(cfd);return 0;
}
  • client.c
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define SERVER_PORT 9527void sysErr(const char* msg) {perror(msg);exit(EXIT_FAILURE);// EXIT_FAILURE	1
}int main(int argc, char const *argv[]) {int cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd == -1) sysErr("socket error");struct sockaddr_in server_addr; // 服务器地址结构server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr.s_addr);int ret = connect(cfd, (struct sockaddr*)&server_addr, sizeof(server_addr));if(ret == -1) sysErr("connect error");int counter = 10;char buf[BUFSIZ];while(counter--) {char *msg = "hello server\n";write(cfd,msg,strlen(msg));ret = read(cfd,buf,sizeof(buf));write(STDOUT_FILENO,buf,ret);sleep(1);}close(cfd);return 0;
}
heheda@linux:~/Linux/test$ gcc server.c -o server -Wall -g
heheda@linux:~/Linux/test$ ./server 
heheda@linux:~/Linux/test$ gcc client.c -o client -Wall -g
heheda@linux:~/Linux/test$ ./client

未完待续~ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/667024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DEV-C++ ege.h库 绘图教程——综合实践(一)

一、First of ALL 学习完了EGE库的所有函数后&#xff0c;今天我们就来综合实践一下。 今天我们将写一个数字华容道来简单练一练手。 准备好了吗&#xff0c;让我们开始。 DEV-C ege.h库 绘图教程合集 二、材料准备 1.音乐 我们可以为我们的游戏增加音乐&#xff0c;这里我…

判断和循环 - switch语句和练习

switch语句格式 switch(表达式) {case 值1:语句体1;break;case 值2:语句体2;break;...default:语句体n1;break; }执行流程&#xff1a; 首先计算表达式的值。依次和case后面的值进行比较&#xff0c;如果有对应的值&#xff0c;就会执行相应的语句&#xff0c;在执行的过程中…

WordPress每天发布60s插件

源码名称:WordPress每天发布60s插件 适用平台:WordPress Wordpress还是比较适合个人博客网站&#xff0c;这个60秒插件适合一些喜欢自动发新闻早报晚报人员 喜欢的赶紧下手。找 万能工具箱合集 小程序即可找到资源

【UE Niagara】环绕在人物周围的闪电效果

效果 步骤 1. 首先下载一个螺旋形状的静态网格体并导入UE&#xff08;地址&#xff1a;https://pan.baidu.com/s/1l9Bn5lQd7tDBu3CMs4c2aA?pwd7myr &#xff09; 2. 创建一个Niagara系统 使用Empty模板 这里命名为“NS_LightingAround” 打开“NS_LightingAround”&#xff0…

大礼包 - 华为机试真题题解

考试平台&#xff1a; 时习知 分值&#xff1a; 200分&#xff08;第二题&#xff09; 考试时间&#xff1a; 2024-01-31 &#xff08;两小时&#xff09; 题目描述 某公司针对新用户推出大礼包&#xff0c;从任意一天注册开始&#xff0c;连续登陆 x 天&#xff0c;每天可以领…

AES算法:数据传输的安全保障

在当今数字化时代&#xff0c;数据安全成为了一个非常重要的问题。随着互联网的普及和信息技术的发展&#xff0c;我们需要一种可靠的加密算法来保护我们的敏感数据。Advanced Encryption Standard&#xff08;AES&#xff09;算法应运而生。本文将介绍AES算法的优缺点、解决了…

Unity引擎学习笔记之【动画剪辑和曲线操作】

动画剪辑和曲线Animation Clip 点选一个包含动画的FBX模型&#xff0c;在其检查器中便可查看动画剪辑 一、动画剪辑 1.Model 2.RIg 538.jpg%20%3D600x&pos_idimg-st6QJc3x-1707050419493) 无动画、旧版Animation动画、普通道具或角色动画、人形角色动画 3.Animation 二…

【动态规划】【树形dp】【C++算法】968监控二叉树

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode:968监控二叉树 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所…

卷死同行!!CSDN博客中所有专栏支持24h无条件退款了。

现在找工作很卷、学习也很卷、做知识付费卖文章卖课也很卷。卷主要提现在内容质量上、内容数量上、售前咨询上(咱有专属客服)、售后服务上… 在CSDN既定的平台下&#xff0c;不能打折、不能设置优惠券、不能改价格、也没有退款按钮的情况下&#xff0c;如何去卷呢&#xff1f;…

[ChatGPT们】ChatGPT 如何辅助编程初探

主页&#xff1a;元存储的博客 全文 9000 字&#xff0c; 原创请勿转载。 我没有写过诗&#xff0c;但有人说我的代码像诗一样优雅 -- 雷军 图片来源&#xff1a;https://www.bilibili.com/video/BV1zL411X7oS/ 1. 引言 作为一个程序员&#xff0c;我们不仅要熟悉各种编程语…

智能决策的艺术:探索商业分析的最佳工具和方法

文章目录 一、引言二、商业分析思维概述三、数据分析在商业实践中的应用四、如何培养商业分析思维与实践能力五、结论《商业分析思维与实践&#xff1a;用数据分析解决商业问题》亮点内容简介作者简介目录获取方式 一、引言 随着大数据时代的来临&#xff0c;商业分析思维与实…

新年心愿清单怎么写 用这个软件列心愿清单更方便

新年的钟声在耳畔回荡&#xff0c;我站在窗前&#xff0c;看着外面熙熙攘攘的人群&#xff0c;心中充满了期待。新的一年&#xff0c;新的开始&#xff0c;我有很多心愿想要实现。于是&#xff0c;我决定写下一份心愿清单&#xff0c;给来年定下奋斗的方向。 但是&#xff0c;…

LLM应用开发与落地:使用gradio十分钟搭建聊天UI

一、背景 如果你是做LLM应用开发的&#xff0c;特别是做后端开发&#xff0c;你一定会遇到怎么快速写一个聊天UI界面来调试prompt或agent的问题。这时候的你可能在苦恼中&#xff0c;毕竟react.js, next.js, css, html也不是每个人都那么熟练&#xff0c;对吧&#xff1f;即使…

CSP-202309-2-坐标变换(其二)

一、遇到问题&#xff1a;迭代计算时间超限 按照常规思路&#xff0c;可以从begin到end逐步计算&#xff0c;共需要约end-begin次运算&#xff0c;时间复杂度较高&#xff0c;导致时间超限。 二、解决思路&#xff1a;累积 1.操作数累积部分 在输入阶段&#xff0c;代码通过…

springboot基于javaWEB的旅游推荐系统设计与实现+vue

随着人民生活水平的提高&#xff0c;对于旅游的需求越来越强烈。目前传统旅游的模式已经无法满足当前消费者的旅游需求。通过分析传统旅游的缺点&#xff0c;我们可以明确传统旅游业无法满足日益多元化的消费者。在消费者追求更加个性化的旅游体验之下&#xff0c;旅游网站就能…

布隆过滤器有什么用?什么原理?如何使用?

1 前言 布隆过滤器相信大家没用过的话&#xff0c;也已经听过了。 布隆过滤器主要是为了解决海量数据的存在性问题。对于海量数据中判定某个数据是否存在且容忍轻微误差这一场景&#xff08;比如缓存穿透、海量数据去重&#xff09;来说&#xff0c;非常适合。 2 什么是布隆…

AI大模型专题:OWASP大语言模型应用程序十大风险V1.0

今天分享的是AI大模型系列深度研究报告&#xff1a;《AI大模型专题&#xff1a;OWASP大语言模型应用程序十大风险V1.0》。 &#xff08;报告出品方&#xff1a;OWASP&#xff09; 报告共计&#xff1a;14页 LM01:2023_ 提示词注入 描述&#xff1a;提示词注入包括绕过过滤器…

云打印机怎么连接手机?

现在越来越多的人使用手机来办公或学习。而当我们需要打印文件时,如何用云打印机连接手机就非常重要了。易绘创云打印服务非常实用&#xff0c;那么易绘创云打印机又该怎么连接手机&#xff1f;下面就让我们一起来了解吧。 云打印机怎么连接手机&#xff1f; 当下云打印机连接…

SolidWorks 2023 使用操作流程

1. 把头 1.1. 新建零件 1.2. 新建草图 1.3. 拉升凸台 1.4. 等距实体 切换到锤头&#xff0c;新建草图&#xff0c;等距实体1mm 1.5. 拉升凸台 将上一个步骤的草图&#xff0c;进行特征拉升 1.6. 镜像处理 1.7. 圆角处理 1.8. 绘制凹槽 在锤子的侧面绘制草图 1.9. 挖出把手孔…

Opencv(C++)学习 TBB与OPENMP的加速效果实验与ARM上的实践(二)

在上一篇文章中&#xff0c;我们成功验证了Intel Threading Building Blocks (TBB) 与 OpenMP 在多线程并行处理方面的加速潜力。为了更深入地理解这些技术在实际应用场景中的效能提升&#xff0c;接下来我们将目光转向目标开发板环境&#xff0c;进一步探究这两种框架在嵌入式…