个人主页:island1314 个人专栏:Linux—登神长阶 1. (从应用层上看,不用看网络栈的底层传输) 要进程间通信,就要先把进程标识出来 2. 认识端口号 定义: 端口号是传输层协议的一部分。 特点: 端口号是一个 2 字节(16 位)的整数 用于标识一个进程,告诉操作系统当前的数据应交给哪个进程处理 IP 地址 + 端口号 可以唯一标识网络上某台主机的某个进程 一个端口号只能被一个进程占用 Socket 编程 6.1 socket 常见API Socket API 是一层网络编程接口,抽象了底层的网络协议,定义在 netinet/in.h 中。 实际上在网络上通信的时候套接字种类是比较多的,下面是常见的三种: unix 域间套接字编程--同一个机器内 原始套接字编程--网络工具 网络套接字编程--用户间的网络通信 设计者想将网络接口统一抽象化
在前面的文章中,我们使用了UDP进行网络编程,这篇文章我们就来使用另一个TCP进行网络编程,我们知道UDP和TCP都是传输层协议,但是特点不同,前者无连接,不可靠传输,面向数据报,后者有连接,可靠传输 大体框架 1.1 补充 首先,在之前的UDP网络编程中,我们是直接使用的硬编码,例如退出码直接就设为1、2、3等,显然这并不是一个很好的选择,那么这里我们可以统一设计一个服务器的退出码,就像之前设计日志等级一样 (网卡)发来的连接我们都愿意接受,所以我们地址结构中的成员 sin_addr 需要设置为 INADDR_ANY,也就是IP地址此时为0,这在UDP网络编程时我们已经详细介绍了原因,这意味着我们服务端在使用 直接向目标服务器发起建立连接的请求 return 0; } 我们这里也不需要显式bind,关于原因我们在udp网络编程时已经说明了,那我们应该做什么呢? ,上层服务我们可以和UDP网络编程一样,直接在服务端主程序调用其他的服务,就比如之前实现的翻译和路由转发,然后在服务端接收数据时,将数据回调处理,最后将结果写回客户端。
Linux Socket编程 ---- 目录 前言 Socket的功能 Socket基础 Socket类型 基本结构 基本转换函数 基本Socket使用 TCP Socket实例 UDP Socket实例 疑难问题记录 总结 ---- 前言 socket(套接字)是网络编程编程的一种技巧。 本篇不涉及太底层的网络原理,仅说明socket的基本使用方法。主要参考《Linux网络编程》。本篇源码获取方式见文底小字。 如果你通过流式套接字发送了顺序的数据:"1"、"2"。那么数据到达远程时候的顺序也是"1"、"2"。 网络编程非常有趣,能够实现天南海北之间的通讯,让远距离的人与人、人与物或者物与物之间产生联系,很有意思! 最后 用心感悟,认真记录,写好每一篇文章,分享每一框干货。
之前我们在学习系统编程的时候知道访问公共资源就是临界资源,那么这里的局域网就是一个临界资源(以太网中, 任何时刻, 只允许一台机器向网络中发送数据)。 : IP 网络层存在的意义: 提供网络虚拟层, 让世界的所有网络都是 IP 网络, 屏蔽 最底层网络的差异 Socket 编程预备 理解源 IP 地址和目的 IP 地址 IP在网络中是用来标识主机的唯一性 到达主机内部, 在交给主机内的进程,才是目的 端口号 端口号(port)是传输层协议的内容 端口号是一个2字节16位整数 端口号标识一个进程,告诉操作系统, 当前的这个数据要交给哪一个进程来处理 IP sockadder结构 socket API 是一层抽象的网络编程接口,适用于各种底层网络协议,如 IPv4、 IPv6,以及 后面要讲的 UNIX Domain Socket. 关于Socket套接字编程后续文章会详细讲解。
文章目录 前言 一、UDP是什么 二、UDP 数据报服务特点 二、UDP 编程流程 1.服务器 2.客户端 3.输出结果 总结 前言 浅谈UDP。 二、UDP 编程流程 1.服务器 代码如下(示例): int main() { int sockfd = socket(AF_INET,SOCK_DGRAM,0); assert( sockfd caddr,&len); printf("buff=%s\n",buff); if(strncmp(buff,"end",3)==0) { break; } sendto(sockfd,"ok",2,0 ,(struck sockaddr*)&caddr,sizeof(caddr)); } close(sockfd); exit(0); } 2.客户端 代码如下(示例): int main() {
例如,在图中主机1向主机2发送数据的过程中,数据的源MAC地址和目的MAC地址的变化过程如下: 时间轴 源MAC地址 目的MAC地址 刚开始 主机1的MAC地址 路由器A的MAC地址 经过路由器A之后 MAC地址 路由器B的MAC地址 经过路由器B之后 路由器B的MAC地址 路由器C的MAC地址 经过路由器C之后 路由器C的MAC地址 路由器D的MAC地址 经过路由器D之后 路由器D的MAC地址 主机2的 端口号是一个2字节16位的整数。 端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理。 一个端口号只能被一个进程占用。 为什么网络字节序采用的是大端?而不是小端? 网络字节序采用的是大端,而主机字节序一般采用的是小端,那为什么网络字节序不采用小端呢? socket编程接口 socket常见接口: 创建套接字:(TCP/UDP,客户端+服务器) int socket(int domain, int type, int protocol); 绑定端口号
TCP/IP协议 TCP/IP 协议栈是一系列网络协议(protocol)的总和,是构成网络通信的核心骨架,它定义了电子设备如何连入因特网,以及数据如何在它们之间进行传输。 OSI 7层模型和TCP/IP四层网络模型对应关系 计算机网路基础的知识不过多讲解,主要是让大家明白接下来的Linux网络编程数据流属于那一层,具体如下图 TCP/IP协议数据流示意图 我们接下来讲解的 Linux网络编程Tcp协议是属于传输层的协议 Linux Socket 网络编程 TCP协议 TCP是面向连接的可靠的传输层协议。 TCP编程 Linux中的网络编程是通过socket接口来进行的。socket是一种特殊的I/O接口,它也是一种文件描述符。常用于不同机器上的进程之间的通信,当然也可以实现本地机器上的进程之间通信。 listen(int sockfd //socket函数返回的套接口描述字 ,int backlog); //则此值表示listen时的队列大小,最大连接个数 listen(listenfd,2)
先要学习网络知识才谈得上编程 讲述计算机网络的最经典的当属Andrew S.Tanenbaum的《计算机网络》第五版,这本书难易适中。 详解的作者还写了另外2本经典著作,《Unix环境高级编程》,《Unix网络编程》二卷本。 说明:搞Linux网络编程的,想学TCP/IP的一定要看大师W.Richard Stevens这六本书,基本上六本书看完基础也就搭好了。 ? ? ? ? ? ? 他的著作有《UNIX网络编程》(两卷本),《UNIX环境高级编程》,《TCP/IP详解》(三卷本)等,同时他还是广受欢迎的教师和顾问。 网络体系结构:linux内核中网络协议的设计与实现》 ?
上篇文章我们实现了英译汉的网络字典,客服端向服务端发送英文,服务端接收数据后回调处理,将翻译后的中文再转发给客户端,这其实和EchoSever一样都是一对一的网络通信。 成功"; _online_user.erase(iter); break; } } } 2. = 2) { std::cerr << "Usage: " << argv[0] << " port" << std::endl; return 1; } } Enable_Console_Log_Strategy(); server_ip = argv[1]; server_port = std::stoi(argv[2] = 2) { std::cerr << "Usage: " << argv[0] << " port" << std::endl; return 1; }
网络通信部分 首先我们网络通信不需要改变,只需要稍微修改添加一些新的变量,服务端在接收客户端发来的数据,然后回调去处理翻译这个动作,所以我们可以使用包装器function来包装一个函数指针,用于回调处理翻译 local)); if(n < 0) { LOG(LogLevel::FATAL) << "bind error"; exit(2) string _ip; // 用的是字符串风格,点分十进制 uint16_t _port; // 端口号 bool _isrunning; func_t _func; }; 2. = 2) { std::cerr << "Usage: " << argv[0] << " port" << std::endl; return 1; } SOCK_DGRAM, 0); if(sockfd < 0) { LOG(LogLevel::FATAL) << "socket error"; return 2;
一,基础概念 数据报文在网络中的点对点传输方式通常有以下三种: 单播(Unicast): 数据报文从一个发送端到一个接收端的通信方式。 接收端: step.01:新建一个socket套接字2用于从组播接收数据报文。 step.02:设置SO_REUSEADDR选项以允许多个接收端去接收同一端口的数据报文。 step.03:调用bind()接口让套接字2绑定到组播指定的端口号。 step.04:使用IP_ADD_MEMBERSHIP选项,加入指定的组播。 Demo2——Python代码实现 发送端: import socket from time import sleep, time MCAST_GRP = '224.1.1.1' MCAST_PORT designs-examples-using-multicasting-af-inet https://os.mbed.com/handbook/Socket https://subingwen.cn/linux
在上篇文章中,我们已经铺垫了一些前置知识,这一篇文章我们就来实现UDP网络编程,实现一个Echo Server,就是客户端给服务端发送一条消息,服务端接收后,再转发给客户端,回显出来 1. :操作系统内核实现了复杂的TCP/IP协议栈,用户不能直接操作这些协议栈,所以我们说它是一组API,是应用程序与网络协议栈之间的编程接口。 这么说也没有毛病 在哲学上:我们认为它是一种抽象和解耦,它隐藏了网络协议的所有复杂性,让程序员可以用“打开-读-写-关闭”这种类似文件操作的简单模式来进行网络编程。 那还说啥了,更没毛病了 用一句话来概括,Socket(套接字)是网络通信的端点,是操作系统提供给应用程序的一组编程接口(API),应用程序通过调用这套接口,就可以利用网络协议栈(如TCP/IP)进行网络通信 2.
网段划分 IP地址分为两部分:网络号和主机号 网络号: 保证相互连接的两个网段具有不同的标识; 主机号: 同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号; 不同的子网其实就是把网络号相同的主机放到一起 如果在子网中新增一台主机,则这台主机的网络号和这个子网的网络号一致, 但 是主机号必须不能和子网中的其他主机重复。 通过合理设置主机号和网络号,就可以保证在相互连接的网络中,每台主机的 IP 地址都 不相同。 那么问题来了, 手动管理子网内的 IP,是一个相当麻烦的事情。 那么一共只有 2 的 32 次方 个 IP 地址,大概是 43 亿左右。而TCP/IP 协议规定,每个主机都需要有一个 IP 地址。 这意味着,一共只有 43 亿台主机能接入网络吗??? ,没有 G 标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发;
它工作在 OSI 模型的第 2 层(数据链路层),主要用于 以太网(Ethernet)、Wi-Fi(802.11)等本地网络通信。 在Linux系统中,我们可以通过ifconfig命令来查看自己机器的MAC地址: ether后面就是mac地址。 IP层的引入屏蔽了底层网络差异(如以太网、Wi-Fi、光纤),通过逻辑化的IP地址实现全球路由,让不同技术的网络能无缝互联。 二、socket编程预备 IP在网络中,用来标识一个主机的唯一性。 2.1、端口号 端口号 (port) 是传输层协议的内容,通常是一个2字节十六位的整数。 端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理。 2.4、sockaddr 结构 socket API 是一层抽象的网络编程接口 , 适用于各种底层网络协议 , 如 IPv4 、 IPv6, 以及后面要讲的 UNIX Domain Socket.
好在Linux内核检测到TCP紧急标志时,将通知应用程序有带外数据需要接收。内核通知应用程序带外数据到达的两种常见方式是: 1O复用产生的异常事件和SIGURG信号。 对这种情况,Linux给开发人员提供的解决方案是:对监听socket设置这些socket选项,那么accept返回的连接socket将自动继承这些选项。 网络信息API 利用域名获取IP地址 IP地址比域名发生变更的概率要高,所以利用IP地址编写程序并非上策。 addrinfo结构体中,ai_ protocol 成员是指具体的网络协议,其含义和socket系统调用的第三个参数相同,它通常被设置为0。ai_fags 成员可以取表中的标志的按位或。 getnameinfo和getaddrinfo函数成功时返回0,失败时返回错误码,可能的错误码如表: Linux下strerror函数能将数值错误码error转换成易读的字符串形式,同样下面的函数可将表错误码转换成字符串形式
智能门锁、电视等等,每一个智能设备都要有一个自己的IP地址,所以我们国家对于IPv6的布置是战略性的,我国是世界上对于IPv6普及最广的国家,当然我们现在包括本文后面一般提到IP协议一般都是IPv4 2、 IP 地址和目的 IP 地址进行的一系列数据封装、传输、路由和交付的操作 IP地址用于不同网络之间寻址,MAC地址用于同局域网传输 二、端口号 1、概念 端口号是传输层协议的内容 端口号是一个16位2 其实,端口号与进程pid,前者用来表示网络内容,后者用来表示系统内容,将网络和系统的内容进行解耦合,在一方出现问题的时候不影响另一方 2、源端口号和目的端口号 源端口号:是在网络通信中,发送数据的应用程序或进程所使用的端口号 而不仅仅是下载邮件到本地 域名系统(DNS):用于将域名解析为对应的 IP 地址,当用户在浏览器中输入域名时,DNS 服务器会将域名转换为对应的 IP 地址,以便浏览器能够找到对应的 Web 服务器 七、socket编程基础 sockaddr的结构 sockaddr的结构如下图左一所示,实际上,我们在函数中用到的结构体是右边两个而不是左一,在sockaddr接受传来的参数时,它会通过判断前面16位2字节的地址类型是AF_INET
相关API笔记(二) Linux网络编程高级I/O函数 1. pipe pipe函数用于创建一个管道,实现进程间通信 #include <unistd.h> //成功返回0,失败返回-1并设置errno ,该新的描述符和原有文件描述符file_descriptor指向相同文件,管道或者网络连接, 并且dup返回的文件描述符总是取系统当前可用的最小整数值。 close(STDOUT); dup(fd); printf("dup"); close(fd); } //使用dup2 void dup2_out(){ dup2(fd iov_base = buf2; iv[1].iov_len = sizeof(buf2); //writev,集中写,把buf1,buf2中的数据写到connfd ret = writev(connfd , iv, 2); //readv,分散读,把键盘的输入读出并放入到buf1,buf2中 ret = readv(STDIN_FILENO, iv, 2); 3. sendfile sendfile函数在两个文件描述符之间直接传递数据
网络编程基本概念 1.1 什么是套接字 套接字,也叫socket,是操作系统内核中的一个数据结构,它是网络中的节点进行相互通信的门户。 2. socket的概念 socket是一种特殊的I/O接口,它也是一种文件描述符。如第一节所说,通过它不仅能实现本地机器上的进程之间的通信,而且通过网络能够在不同机器上的进程之间进行通信。 Ipv6地址),而在socket编程中使用的则是32位的网络字节序的二进制值,这就需要对这两个数值进行转换。 在linux中,最常用的是gethostbyname()和gethostbyaddr(),它们都可以实现IPv4/IPv6的地址和主机名之间的转化。 char **argv) { char *ptr, **pptr; struct hostent *hptr = NULL; char str[32] = {0}; if ( argc < 2
相关API笔记(一) Linux网络编程基础API 1. 长整型函数 (htonl,ntohl)通常用来转换IP地址 短整型函数 (htonl,ntohl)通常用来转换端口号 2. 通用socket地址 这个比较少用 socket网络编程接口中表示socket地址的是结构体sockaddr #include <bits/socket.h> struct sockaddr{ } 实际使用时(包括sockaddr_storage)都需要将其转化为通用的socket地址类型sockaddr(强制转换即可),所以的socket编程接口使用的类型都是sockaddr。 窥探读缓存中的数据,此次读操作不会导致这些数据被清楚 N Y MSG_OOB 发送或接收紧急数据 Y Y MSG_NOSIGNAL 往读端关闭的管道或者socket连接中写数据时不引发SIGPIPE信号 Y N 2.
今天我们终于进入了网络编程的学习。 实际上,网络也属于操作系统的一环,我们想要学好操作系统,自然也需要去学习网络编程。 今天我们将会介绍一下网络的基础概念。 网络编程的学习与系统部分不一样,这一部分会多许多概念,我们学习的方式也更注重与概念而不是代码。 所以希望大家调整一下学习的思路。 一、计算机网络连接模式的演进 1. 独立模式 (Standalone) 特点:计算机完全独立运行 数据交互:依赖物理介质(软盘/磁带)人工传递 局限性:资源无法实时共享,效率低下 2. 2、OSI 七层模型 OSI(Open Systems Interconnection)七层模型是国际标准化组织(ISO)提出的网络通信概念框架,它将网络通信过程划分为七个逻辑层次。 应用层 : 负责应用程序间沟通,如简单电子邮件传输( SMTP )、文件传输协议(FTP )、网络远程访问协议( Telnet )等 . 我们的网络编程主要就是针对应用层 .