最后更新:2022-07-01 19:57:31 手机定位技术交流文章
本地进程间通信(IPC)有多种方式,但可以归纳为以下四个类别:
消息传输(管道、FIFO、消息队列)
同步(相互数量,条件变量,读写锁,文件和写记录锁,信号数量)
共享记忆(匿名和匿名)
远程过程调用(Solaris Gate和Sun RPC)
如何在网络中沟通进程?解决的第一个问题是如何以独特的方式确定一个过程,否则通信无从谈起!只有一个进程可以由进程PID lokally识别,但它在网络上并不有效。事实上,TCP/IP协议家族帮助我们解决这个问题,网络层的"ip地址"只能识别网络中的主机,传输层的“协议+端口”只能识别主机中的应用程序(进程)。使用一个三维群(IP地址,协议,能够识别网络的进程,网络中的进程通信可以使用这个符号与其他进程交互。
索克源自Unix,而Unix/ Linux 一个基本的哲学是,所有东西都是文件。都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。索克是这一模型的实现之一,索克是一个特殊的文件,一些插座函数是操作(read/write IO, open, close)。
索克是应用层和TCP/IP协议家族通信的中间软件抽象层。它是一组接口。在设计模式中,插座实际上是一个从门到门的模型,它隐藏了 Socket接口背后的复杂TCP/IP协议家族,对用户来说,简单的接口就是一切。让索克特组织数据,以符合指定的协议。
注:接口没有层的概念,只是一个学术设计模式的应用,使编程变得更简单。 它是软件抽象层。
索克是网络编程的一个抽象概念,我们通常使用索克表示“打开网络链接”,而为了打开索克,你需要知道目标计算机的IP地址和端口号,然后指定协议类型。
使用TCP/IP协议的应用程序通常使用应用程序编程接口:UNIX BSD的插座和UNIX System V的TLI(这些接口已经被取消)用于通信网络进程。
TCP/IP协议家族由传输层、网络层和链路层组成,接口是应用程序层和TCP/IP协议家族通信的中间软件抽象层。

目前,几乎所有应用程序都使用插座,这是互联网时代,处理通信在网络中到处都有,这就是为什么我所说的“所有插座”。
网络编程是所有开发语言一样的,而Python也不例外。 与Python的网络编程是在Python程序本身中进行的,通过连接其他服务器进程的通信端口来进行通信。
Python提供了两个层次的网络访问:
索克是网络编程的一个抽象概念,我们通常使用索克表示“打开网络链接”,而为了打开索克,你需要知道目标计算机的IP地址和端口号,然后指定协议类型。
应用程序通常通过“切换”向网络发送请求,或响应网络请求,以允许在计算机上的主机或进程之间进行通信。
索克和文件之间的区别:

服务器终止以初始化接口,然后绑到端子上,听着港口,调用接受块,等待客户端连接。此时,如果客户端启动一个接口,然后连接服务器,如果连接成功,此时,客户端与服务器之间的连接已经建立。客户发送数据请求,在服务器端接收请求和处理请求,然后向客户发送响应数据,客户端读取数据,最后关闭连接,一次交互结束。
应用程序通常通过“切换”向网络发送请求,或响应网络请求,以允许在计算机上的主机或进程之间进行通信。

索克特()函数
在Python中,我们使用Socket()函数创建一个索克。语法格式如下:
参数
SOCK_STREAM或SOCK_DGRAM。索克对象(集成)方法:
| 函数 | 描述 |
|---|---|
| 服务器端套接字 | |
| s.bind() | 地址(主机,端口)被绑定到插座上,在AF_INET中,地址以子集的形式表示(主机,端口)。 |
| s.listen() | 启动TCP surveillance.backlog 指定操作系统在拒绝连接之前可以挂挂的最大连接数。 该值至少为1,大多数应用程序设置为5。 |
| s.accept() | 被动接受TCP客户端连接,(封锁)等待连接到达 |
| 客户端套接字 | |
| s.connect() | 主动启动TCP服务器连接。 一般地址格式是主机名端口,如果连接失败,则返回接口。 |
| s.connect_ex() | 连接()函数的扩展版本在发生错误时返回错误代码,而不是抛出异常 |
| 公共使用的插座功能 | |
| s.recv() | 接收的TCP数据,以字符串形式返回,并指定接收的最大数据量。 flag提供其他信息,这些信息通常可以忽略。 |
| s.send() | 发送TCP数据,将字符串中的数据发送到连接接口。 返回值是发送的字节数,可能比字符串的大小小。 |
| s.sendall() | 完全发送TCP数据。 将字符串中的数据发送到连接的插座上,但尝试在返回之前发送所有数据。 |
| s.recvfrom() | 接收UDP数据,类似 recv(),但返回值(数据,地址)。 数据是一个包含接收数据的字符串,地址是发送数据的插座地址。 |
| s.sendto() | 发送UDP数据,发送数据到一个接口,地址是(ipaddr,port)形式的组件,并指定远程地址。 |
| s.close() | 关闭套接字 |
| s.getpeername() | 返回连接插座的远程地址。 返回值通常是一个组件(ipaddr, port)。 |
| s.getsockname() | 返回索克本身的地址。 通常是一个组件(ipaddr,port) |
| s.setsockopt(level,optname,value) | 设置预设插座类型选项的值。 |
| s.getsockopt(level,optname[.buflen]) | 返回插座选项的值。 |
| s.settimeout(timeout) | 时限是一个浮点数,单位是秒数。 None 的值表示没有过时。 一般来说,当接口刚创建时应该设置过时,因为它们可以用于连接操作(例如 connect()) |
| s.gettimeout() | 返回当前剩余时间的值,以秒为单位,如果剩余时间没有设置,则返回无值。 |
| s.fileno() | 返回索克的文件描述符。 |
| s.setblocking(flag) | 如果flag为0,然后将插座设置为非锁定模式,否则, 将接口设置为块模式(默认值).非阻塞模式下,如果callrecv()找不到任何数据,或发送()电话不能立即发送数据,然后会造成一个索克.error异常。 |
| s.makefile() | 创建与此接口关联的文件 |
详细用法:
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
参数一:地址簇
socket.AF_INET IPv4(默认)
socket.AF_INET6 IPv6
socket.AF_UNIX只能用于单一的Unix系统进程间通信
参数二:类型
socket.SOCK_STREAM流索克,用于TCP(默认)
socket.SOCK_DGRAM 数据声明索克,用于UDP
socket.SOCK_RAW原先的索克,普通接口不能处理像ICMP、IGMP、SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊IPv4消息;此外,利用原始套接字,用户可以通过IP_HDRINCL接口选项构造IP头条。
socket.SOCK_RDM是一个可靠的UDP格式。也就是说, 保证数据报告的交付, 但不能保证订单.SOCK_RAM用于提供低级别访问原始协议,在执行某些特殊操作时使用,例如,发送一个ICMP消息。SOCK_RAM通常只限于高级用户或管理员运行的应用程序。
socket.SOCK_SEQPACKET可靠的连续包服务
参数三:协议
0(默认)是一个与特定地址家族关联的协议。如果它为0,系统将根据地址格式和插座类别自动选择适当的协议
sk.bind(address)
s.bind(address)将一个接口绑定到一个地址。 地址的格式取决于地址家族。
sk.listen(backlog)
开始倾听接入的连接。 后队列指定在拒绝接入之前可以悬挂的最大连接数。
backlog等于5,表明内核收到了连接请求,但服务器没有调用 accept 处理最多5个连接
这个值不能无限大,因为它维护了内核中的连接队列
sk.setblocking(bool)
是否要封锁(Default True),如果 false是设置的,那么在接受 andrecv时没有数据时就会报告错误。
sk.accept()
接受连接和返回(conn,address),其中conn是一个新的接口对象,可以用于接收和发送数据。
接收TCP客户端连接(阻塞)等待连接到达
sk.connect(address)
将接口连接到地址。 一般来说,地址格式是主机名端口,如果接口失败,则返回接口。
sk.connect_ex(address)
同样,只有一个返回值,当连接成功时返回0,当连接失败时返回代码,例如:10061
sk.close()
关闭套接字
sk.recv(bufsize[,flag])
接受索克的数据。 数据以字符串形式返回,Bufsize指定可以接收的最大数目。 flag提供其他信息,这些信息通常可以忽略。
sk.recvfrom(bufsize[.flag])
它类似于torecv(),但返回值是(data,address)。 数据是一个包含接收数据的字符串,地址是发送数据的接口地址。
sk.send(string[,flag])
发送一个字符串的数据到连接接口。 返回值是发送的字节数,可能比字符串的字节大小小。
sk.sendall(string[,flag])
将字符串中的数据发送到连接的插座上,但尝试在返回之前发送所有数据。
通过递归调用发送来内部发送所有内容.
sk.sendto(string[,flag],address)
为发送数据到一个接口,地址是(ipaddr,port)形式的组件,指定远程地址。 返回值是发送的字节数。
sk.settimeout(timeout)
时限是浮点数,单位是秒数。 None 的值表示没有过时。 一般来说,当您刚创建插座时应该设置过时,因为它们可以用于连接操作(例如客户连接等于5秒)。
sk.getpeername()
返回连接插座的远程地址。 返回值通常是一个组件(ipaddr, port)。
sk.getsockname()
返回索克本身的地址。 通常是一个组件(ipaddr,port)
sk.fileno()
套接字的文件描述符
简单的例子:客户端到服务接口通信
服务端
我们使用插座模块的插座函数创建插座对象。 插座对象可以通过调用其他函数设置插座服务。
现在我们可以通过调用 bind(hostname, port)函数来指定服务port(端口)。
然后我们称之为接口对象accept方法:此方法等待客户端连接并返回connection指示它与客户端连接的对象。
完整代码如下:
客户端
接下来我们写一个简单的客户端例,连接到上面创建的服务。
如何打开到主机的TCP连接如下:hostname端口为port服务提供者:在连接后,我们可以从服务端获取数据,记住在操作完成后关闭连接。
完整代码如下:
现在我们打开两个终端,第一个执行 server.py文件:
第二个终端执行 client.py文件:
当我们再次打开第一个终端时,我们可以看到以下信息输出:
简单的例子:智能机器人
服务端:
客户端:
Python互联网模块
下面列出了Python网络编程的一些重要模块:
| 议 | 功能用处 | 端口号 | Python 模块 |
|---|---|---|---|
| HTTP | 网页访问 | 80 | httplib, urllib, xmlrpclib |
| NNTP | 阅读和发布新闻文章,通常称为“邮件” | 119 | nntplib |
| FTP | 文件传输 | 20 | ftplib, urllib |
| SMTP | 发送邮件 | 25 | smtplib |
| POP3 | 接收邮件 | 110 | poplib |
| IMAP4 | 获取邮件 | 143 | imaplib |
| Telnet | 命令行 | 23 | telnetlib |
| Gopher | 信息查找 | 70 | gopherlib, urllib |
TCP/IP(Transmission Control Protocol/Internet Protocol)是用于宽带网络(WAN)的工业标准协议集。
TCP接口比UDP接口复杂,因为它们需要在前进过程中建立连接。
当您编写一个接口应用程序时,您可以选择使用TCP或UDP,它们都有自己的优点和缺点。
TCP是流协议,UDP是一个数据报告协议。换句话说,TCP在客户端和服务器之间建立连续的开放连接,在连接的一生中,句子可以从连接中写出来(并确保正确的序列)。然而,通过TCP编写的字符串没有内置结构,因此,需要高级别协议来部分地孤立传输节点流中的数据记录和字段。
另一方面,UDP不需要建立客户端与服务器之间的连接,它只能在地址之间发送消息。UDP的一个优点是它的包是自定义的。也就是说, 数据报告准确地指出它的起点和终点位置.然而,开发计划署的一个可能的缺点是,它不保证包裹会按时到达,甚至根本就不保证。当然,基于UDP的高级协议可以提供握手和确认功能。
为了了解TCP和UDP之间的区别,一个有用的比较是电话和邮件之间的区别.呼叫者通过铃声通知接收者,在接收器拿起耳机之前,电话不活跃。只要没有一方挂断,电话渠道仍然活跃,但是在通话期间,他们可以自由地说他们想要的。任何一方的会谈都按临时顺序进行.另一方面,当你寄信时,邮政局不得对收件人在交货时是否存在给予任何保证,也 没有 强有力 的 保证, 将 需要 多久 才能 交出 信件 。受信者可能收到不同顺序的讯息,而不是发送的顺序,发件人也可以接受邮件,以换取他们所发的发件人。与(理想)邮政服务不同,不能交付的信件总是送往死信办公室处理。而不再返回给发送。
除了TCP和UDP协议外,通信者(客户或服务器)也需要了解与它通信的另一台机器的两个东西:IP地址或端口。IP地址是一个32位数据值,为了人们好记,一般表达为四组由圆区分开的数字,例如:端口是一个16位数据值,它通常以小于65536的数字表示。大多数情况下,值在10到100之间。一个IP地址获取发送给机器的数据包,一个端口允许机器决定给数据包提供哪些过程/服务(如果有的话)。这种解释略显简单,但基本的想法是正确的。
以上描述几乎是正确的,但它也把某些东西排除在外。大多数时候,当人们想到互联网主机时(相反),我们不会记住这样的数字。像gnosis一样的记忆,像cx这样的名称。找到与特定主机名称关联的IP地址,通常使用的域名服务器(DNS),然而,有时首先使用本地搜索(通常通过/etc/hosts内容)。对于本教程,我们一般认为一个IP地址是可用的,然而,下面讨论了编写名称搜索代码。
nslookup命令行工具可以用来根据符号名称搜索主机IP地址。 事实上,许多常见的工具,例如 ping或网络配置工具,也这样做。
======================TCP/IP======================
应用程序层:仅负责生成数据在相应的格式 ssh ftp nfs cifs dns http smtp pop3
-----------------------------------
传输层: 定义数据传输有两种方式:
TCP(传输控制协议:面向连接,可靠,相对效率低)
UDP(用户数据报告协议:非连接导向,不可靠,但高效)
-----------------------------------
网络层:连接到不同的网络,如Ethernet、授权环路网络
IP、ICMP、IGMP
ARP ( 地址分析协议, 用于分析IP到MAC )
-----------------------------------
数据链层:以太网传输
-----------------------------------
物理层:主要任务是确定与传输信号有关的各种传输介质和接口的特性
-----------------------------------
TCP编程:
索克是网络编程的一个抽象概念,我们通常使用索克表示“打开网络链接”,而为了打开索克,你需要知道目标计算机的IP地址和端口号,然后指定协议类型。
TCP连接摘要: 三个握手, 数据传输, 四个握手.

我们知道tcp建立连接需要“三个握手”,即交换三个分组。
它只做了三个抖动,但是这些抖动有多少在插座功能中发生?

从图中可以看出,当客户调用连接时,触发了连接请求,向服务器发送SYN J包,这是当连接进入阻塞状态时;服务器听取连接请求时,收到SYNJ包,调用接受函数接收发送SYNK到客户端的请求,ACK J+1,客户端接收服务器的SYN K。在ACKJ+1之后,然后连接返回,并确认SYN K;当服务器接收ACK K+1时,accept返回,至此三次握手完毕,连接建立。
摘要:客户端的连接返回三个握手中的第二个,而服务器的接受返回三个握手中的第三个。
通过四个手在插座中释放连接的过程。

图示过程如下:
一个应用程序进程首先呼叫,以积极关闭连接,而TCP发送 FIN M;
在另一端接收FINM后,执行消极关闭来确认该FIN。 该FIN的接收也作为文件终止器传递到应用程序进程中,因为FIN的接收意味着应用程序进程不能再接收有关连接上的额外数据。
经过一段时间后,收到文件终止器调用的申请过程关闭了其接口,导致其TCP也发送了 FIN N;
接收此 FIN的源TCP确认它。
所以每个方向都有一个 FIN和一个 ACK。
大多数连接是可靠的TCP连接。创建TCP连接时,调用客户端启动连接,调用服务器对连接作出消极反应。
我们想创建一个基于TCP连接的接口,我们可以做以下:
客户端:
创建Socket时,AF_INET指定使用IPv4协议。如果您要使用更先进的IPv6,请指定为AF_INET6。SOCK_STREAM指定一种面向流的TCP协议,使得一个Socket对象创建成功,但连接尚未建立。
为启动TCP连接,客户端必须知道服务器的IP地址和端口号码。 Sina网站的IP地址可以作为域名www.sina.com.cn自动转换到IP地址, 但如何知道西纳服务器的端口号码?
答案是,作为服务器,无论它提供什么服务,都必须固定其端口号码。 因为我们想要访问网络, Sina提供的服务器必须固定其端口号码80端口,因为80其他服务都有相应的标准端口号码,例如SMTP服务是25端口,FTP服务是21终端,等候。 1024 以下的终端是互联网标准服务的终端, 1024 以上的终端可以随时使用。
因此,我们将Sina服务器代码连接如下:
注意参数是一个tuple包括地址和港口号码。
在建立TCP连接后,我们可以向Sina服务器发送请求,请求返回主页的内容:
例如,HTTP协议要求客户端先向服务器发送请求,然后服务器在收到请求后向客户端发送数据。
发送的文本格式必须符合HTTP标准。如果格式是好的,则Sina服务器返回的数据可以得到。
接收数据时,调用recv(max)方法,最多一次接收指定的字节数目,以便在一段时间循环中重复接收到recv()返回空数据, 表明它已经收到,并退出循环.
收到数据后,请打电话close()方法关闭插座, 以便完成网络通信.
接收的数据包括HTTP头条和网络本身,我们只需要将HTTP头条与网络分开,打印出HTTP头条,并将网络内容保存到文件中。
现在,你只需要在浏览器中打开这个sina.html文件, 你可以看到西纳的网页.
服务端:
服务器编程比客户端编程更复杂。
服务器进程首先绑定一个端口并监视其他客户端的连接。 如果一个客户端连接,服务器将与客户端建立一个索克连接,随后的通信由这个索克连接。
所以,服务器将打开一个固定的端口(例如80)来听,每个客户连接,创建插座连接。因为服务器将有许多来自客户端的连接,所以,服务器必须能够区分哪个接口连接与哪个客户端是绑定的.一个接口依靠四个元素:服务器地址、服务器端口、客户端地址和客户端端口来确定一个接口。
但服务器也需要同时响应多个客户端的请求,因此每个连接需要处理一个新的进程或线程,否则服务器只能一次服务一个客户端。
让我们写一个简单的服务器程序来接收客户端连接并添加客户端发送的字符串Hello再发回去。
首先,创建一个基于IPv4和TCP协议的插座:
然后我们将监视地址和端口绑定。 服务器可能有多个网络卡,可以绑定到特定网络卡的IP地址,也可以使用0.0.0.0连接到所有网络地址,也可以使用127.0.0.1绑定到本机地址。127.0.0.1一个IP地址是指定主机地址的特殊IP地址,如果绑定到这个地址,客户端必须在主机上同时运行连接,也就是说,外部计算机不能连接。
由于我们写的服务不是标准服务,请使用9999这是港口号码,请注意,小于1024端口号必须有管理员权限被绑定.
紧接着,调用listen()方法开始监视端口,输入参数指定等待连接的最大数目。
然后,服务器程序通过永久循环接受客户端的连接,accept()等待并返回客户端连接。
每个连接必须创建一个新的线程(或进程)来处理,否则单个线程不会在处理连接时接受其他客户端的连接。
连接建立后,服务器首先发送欢迎消息,然后等待客户端数据,并添加Hello发送给客户。 如果客户发送exit字符串直接关闭连接.
为了测试这个服务器程序, 我们需要写一个客户端程序.
我们需要打开两个命令行窗口,一个运行服务器程序,另一个运行客户端程序,你可以看到效果。
UDP编程:
TCP是建立可靠的连接,通信双方可以以流的形式发送数据。 与TCP相反,UDP是一个不连接的协议。
使用UDP协议,不需要创建连接,只需要知道对方的IP地址和端口号码来直接发送数据包。
尽管UDP数据不可靠,但它具有比TCP更快的优点,并且可以在UDP协议中用于不需要可靠访问的数据。
UDP插座服务器端口代码不需要在绑定后调用听法。

让我们看看如何通过UDP协议传输数据,和TCP一样,UDP通信的两个方面都分为客户端和服务器。
服务器首先需要一个绑定端口:
创建索克时,SOCK_DGRAM该插座指定的类型是UDP。 绑定端口与TCP相同,但不需要调用listen()方法,而不是直接从任何客户接收数据。
recvfrom()方法返回数据和客户端的地址和端口,让服务器在接收数据后直接呼叫sendto()您可以使用UDP向客户端发送数据。
注意这里没有额外的线程,因为这个例子很简单。
当客户端使用UDP时,它首先创建基于UDP的接口,然后不需要调用connect(),直接通过sendto()给服务器发数据。
从服务器接收数据仍被调用recv()方法。
UDP使用与TCP相似,但不需要连接。 此外,服务器绑定的UDP和TCP端口互不冲突,即UDP的99端口可以分别绑定到TCP的99端口。
完整案例1:
完整案例2:
本文由 在线网速测试 整理编辑,转载请注明出处。