python3全栈开发,_Socket互联网编制程序

一,socket用法

互连网协议参考:http://www.cnblogs.com/hedeyong/p/6889774.html

① 、 客户端/服务器架设

1.硬件C/S架构(打印机)

2.软件C/S架构

*  *互连网中随地是C/S架构

  如巴黎绿网站是服务端,你的浏览器是客户端(B/S架构也是C/S框架结构的一种)

  腾讯当作服务端为你提供录像,你得下个腾讯摄像客户端才能看它的录像)

C/S架构与socket的关系:

咱俩学习socket就是为着达成C/S架构的成本

 一 、服务端和客户端

BS架构 (腾讯通软件:server+client)

CS架构 (web网站)

 

C/S架构与socket的关系:

咱俩上学socket正是为着完成C/S架构的开支

socket是什么 ?

Socket是应用层与TCP/IP协议族通讯的中档软件抽象层,它是一组接口。在设计情势中,Socket其实正是二个伪装形式,它把纷纷的TCP/IP协议族隐藏在Socket接口前边,对用户来说,一组大致的接口正是一体,让Socket去协会数据,以适合钦定的商议。

据此,大家无需深刻领会tcp/udp协议,socket已经为大家封装好了,大家只要求依照socket的明确去编制程序,写出的先后自然就是鲁人持竿tcp/udp标准的。

一、TCP/IP五层模型

澳门葡京备用网址 1

上学socket一定要先读书互连网协议:

1.先是:本节科指标对象正是教会你怎么样依据socket编制程序,来支付一款本人的C/S架构软件

2.其次:C/S架构的软件(软件属于应用层)是依照网络开始展览通讯的

3.然后:网络的主导即一堆协议,协议即规范,你想付出一款基于互联网通讯的软件,就务须根据这几个专业。

4.终极:就让我们从那些专业伊始商讨,开启大家的socket编制程序之旅

澳门葡京备用网址 2

二、 osi七层

引子:

  须知三个总体的微型总结机连串是由硬件、操作系统、应用软件三者结合,具备了那八个尺码,一台总结机种类就足以协调跟本身玩了(打个单机游戏,玩个扫雷啥的)

万一你要跟人家伙同玩,那您就须求上网了,什么是互连网?

互连网的中央正是由一堆协议组成,协议就是正式,比如全球人通讯的正式是斯洛伐克共和国(The Slovak Republic)语

要是把电脑比作人,互连网球组织议就是计算机界的拉脱维亚语。全数的计算机都学会了网络球组织议,那拥有的总计机都就足以遵循联合的科班去收发音信之所以达成通讯了。

大千世界依据分工区别把互连网球组织议从逻辑上划分了层级,

详细网络通信原理:http://www.cnblogs.com/linhaifeng/articles/5937962.html

 

澳门葡京备用网址 ,为什么学习socket一定要先读书网络球协会议:

python3全栈开发,_Socket互联网编制程序。1.先是:本节科目标对象正是教会你什么依照socket编制程序,来开发一款自身的C/S架构软件

2.其次:C/S架构的软件(软件属于应用层)是基于互联网展开通信的

3.然后:互连网的焦点即一堆协议,协议即规范,你想付出一款基于网络通讯的软件,就必须服从那几个专业。

4.尾声:就让大家从那几个专业起先研商,开启大家的socket编制程序之旅

                                                     
                        
澳门葡京备用网址 3
                                                     
     图1

二 、OSI七层模型

套接字的发展史及分类

套接字源点于 20 世纪 70 时代亚拉巴马大学Berkeley分校版本的
Unix,即人们所说的 BSD Unix。
由此,有时人们也把套接字称为“Berkeley套接字”或“BSD
套接字”。一伊始,套接字被规划用在同
一台主机上两个应用程序之间的通信。那也被称经过间通信,或
IPC。套接字有二种(也许叫做有八个种族),分别是依照文件型的和根据网络型的。 

据他们说文件类型的套接字家族

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的正是底层的文件系统来取数据,七个套接字进度运维在同一机器,可以透过访问同三个文件系统间接实现通讯

遵照互联网项目标套接字家族

套接字家族的名字:AF_INET

(还有AF_INET6被用来ipv6,还有部分任何的地点家族,不过,他们或然是只用于某些平台,要么就是现已被撇下,也许是很少被使用,只怕是向来没有兑现,全部地点家族中,AF_INET是采用最常见的四个,python帮忙很多种地点家族,然则由于大家只关注互连网编程,所以当先二分之一时候小编么只利用AF_INET)

二、socket层

  Socket是应用层与TCP/IP协议族通讯的中档软件抽象层,它是一组接口。在设计方式中,Socket其实正是叁个外衣形式,它把复杂的TCP/IP协议族隐藏在Socket接口后边,对用户来说,一组容易的接口便是总体,让Socket去协会数据,以合乎钦定的商谈。

 澳门葡京备用网址 4

  之所以,我们无需深远理解tcp/udp协议,socket已经为大家封装好了,我们只须求遵照socket的规定去编程,写出的次第自然正是遵照tcp/udp标准的。

 

 

三 、socket层

在图第11中学,大家从未见到Socket的黑影,那么它毕竟在哪儿吗?照旧用图来讲话,一目精通。 

澳门葡京备用网址 5

 图2

互联网球组织议遵照效益不一样分为osi七层或tcp/ip五层或tcp/ip四层

澳门葡京备用网址 6

上学socket一定要先读书互连网球组织议:

1.率先:本节课程的对象就是教会你什么样依照socket编制程序,来支付一款融洽的C/S架构软件

2.其次:C/S架构的软件(软件属于应用层)是基于网络展开通讯的

3.然后:网络的骨干即一堆协议,协议即标准,你想付出一款基于互联网通讯的软件,就非得根据那几个专业。

4.说到底:就让大家从那个专业早先商量,开启大家的socket编制程序之旅

澳门葡京备用网址 7

socket:便是位于 应用层和传导层
之间。socket帮大家封装了一多级协议,统一标准。

澳门葡京备用网址 8

 套接字工作流程

 一个在世中的场景。你要打电话给3个对象,先拨号,朋友听到电话铃声后提起电话,那时你和您的爱人就创造起了延续,就能够说话了。等交换停止,挂断电话结束本次交谈。 生活中的场景就分解了那工作规律。

澳门葡京备用网址 9 
    

                                           图3    
  

先从服务器端说起。服务器端先起先化Socket,然后与端口绑定(bind),对端口举行监听(listen),调用accept阻塞,等待客户端连接。在此刻假若有个客户端初叶化2个Socket,然后连接服务器(connect),假诺老是成功,那时客户端与服务器端的总是就创设了。客户端发送数据请求,服务器端接收请求并拍卖请求,然后把应对数据发送给客户端,客户端读取数据,最后关闭连接,二遍交互甘休

服务端套接字函数
s.bind()    绑定(主机,端口号)到套接字
s.listen()  开始TCP监听
s.accept()  被动接受TCP客户的连接,(阻塞式)等待连接的到来

客户端套接字函数
s.connect()     主动初始化TCP服务器连接
s.connect_ex()  connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

公共用途的套接字函数
s.recv()            接收TCP数据
s.send()            发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
s.sendall()         发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
s.recvfrom()        接收UDP数据
s.sendto()          发送UDP数据
s.getpeername()     连接到当前套接字的远端的地址
s.getsockname()     当前套接字的地址
s.getsockopt()      返回指定套接字的参数
s.setsockopt()      设置指定套接字的参数
s.close()           关闭套接字

面向锁的套接字方法
s.setblocking()     设置套接字的阻塞与非阻塞模式
s.settimeout()      设置阻塞套接字操作的超时时间
s.gettimeout()      得到阻塞套接字操作的超时时间

面向文件的套接字的函数
s.fileno()          套接字的文件描述符
s.makefile()        创建一个与该套接字相关的文件

 

叁 、套接字发展史及分类

  套接字起点于 20 世纪 70 时代阿肯色高校伯克利分校版本的
Unix,即人们所说的 BSD Unix。
因而,有时人们也把套接字称为“Berkeley套接字”或“BSD
套接字”。一起始,套接字被规划用在同
一台主机上多少个应用程序之间的通信。那也被称经过间通信,或
IPC。套接字有两种(大概叫做有多少个种族),分别是基于文件型的和基于网络型的。 

据说文件类型的套接字家族

  套接字家族的名字:AF_UNIX

  unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,四个套接字进程运维在同一机器,可以透过拜访同二个文件系统直接完结通讯

 

依照网络项指标套接字家族

  套接字家族的名字:AF_INET

  (还有AF_INET6被用来ipv6,还有一些其余的地点家族,但是,他们也许是只用于有些平台,要么就是早就被丢掉,恐怕是很少被运用,大概是历来未曾落到实处,全数地方家族中,AF_INET是运用最常见的多个,python协理很八种地址家族,不过由于大家只关心网络编制程序,所以大多数时候笔者么只使用AF_INET)

四 、socket是什么

Socket是应用层与TCP/IP协议族通讯的高级中学级软件抽象层,它是一组接口。在设计格局中,Socket其实正是八个门面方式,它把纷纭的TCP/IP协议族隐藏在Socket接口前边,对用户来说,一组简单的接口正是百分百,让Socket去组织数据,以符合钦点的磋商。

所以,我们无需深刻明白tcp/udp协议,socket已经为大家封装好了,大家只必要依照socket的显然去编制程序,写出的主次自然正是依据tcp/udp标准的。

澳门葡京备用网址 10澳门葡京备用网址 11

也有人将socket说成ip+port,ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序,ip地址是配置到网卡上的,而port是应用程序开启的,ip与port的绑定就标识了互联网中独一无二的一个应用程序

而程序的pid是同一台机器上不同进程或者线程的标识

扫盲区

三、socket是什么?

Socket是应用层与TCP/IP协议族通信的高级中学级软件抽象层,它是一组接口。在设计格局中,Socket其实正是二个外衣方式,它把复杂的TCP/IP协议族隐藏在Socket接口后边,对用户来说,一组简单的接口便是整套,让Socket去组织数量,以符合钦点的情商。

故而,大家无需深刻精晓tcp/udp协议,socket已经为大家封装好了,大家只要求依照socket的规定去编制程序,写出的次第自然正是遵照tcp/udp标准的。

1,先用socket落成2个大概的ssh

ssh服务端

澳门葡京备用网址 12澳门葡京备用网址 13

1 import socket,os
 2 server=socket.socket()
 3 server.bind(('127.0.0.1',1314))
 4 server.listen()
 5 while True:
 6     conn,addr=server.accept()
 7     try:
 8         while True:
 9             data=conn.recv(1024)
10             print('客户端发来的命令是:',data.decode())
11             if not data:break
12             if len(data)==0:
13                 print('命令为空')
14             send_data=os.popen(data.decode()).read()#执行命令,并读出结果
15             conn.send(send_data.encode())
16     except ConnectionResetError as e:
17         print('一个客户端断开连接')
18     conn.close()
19 server.colse()

View Code

ssh客户端

澳门葡京备用网址 14澳门葡京备用网址 15

1 import socket
 2 client=socket.socket()
 3 client.connect(('127.0.0.1',1314))
 4 while True:
 5     data=input('>>>')
 6     if len(data)==0:continue
 7     client.send(data.encode())
 8     recv_data=client.recv(1024)
 9     print(recv_data.decode())
10 client.close()

View Code

四 、套接字工作流程

澳门葡京备用网址 16

  先从服务器端说起。服务器端先初始化**Socket,然后与端口绑定**(bind),对端口举办监听**(listen),调用accept阻塞伺机客户端连接**。在那时候若是有个客户端先河化三个Socket,然后连接服务器(connect),即便连接成功,那时客户端与劳动器端的一而再就创立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一遍交互结束

服务端套接字函数

s.bind()    绑定(主机,端口号)到套接字
s.listen()  开始TCP监听
s.accept()  被动接受TCP客户的连接,(阻塞式)等待连接的到来

客户端套接字函数

s.connect()     主动初始化TCP服务器连接
s.connect_ex()  connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

公家用途的套接字函数

s.recv()            接收TCP数据
s.send()            发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
s.sendall()         发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
s.recvfrom()        接收UDP数据
s.sendto()          发送UDP数据
s.getpeername()     连接到当前套接字的远端的地址
s.getsockname()     当前套接字的地址
s.getsockopt()      返回指定套接字的参数
s.setsockopt()      设置指定套接字的参数
s.close()           关闭套接字

面向锁的套接字方法

s.setblocking()     设置套接字的阻塞与非阻塞模式
s.settimeout()      设置阻塞套接字操作的超时时间
s.gettimeout()      得到阻塞套接字操作的超时时间

面向文件的套接字的函数

s.fileno()          套接字的文件描述符
s.makefile()        创建一个与该套接字相关的文件

  

 

伍 、 套接字发展史及分类

套接字起点于 20 世纪 70 时期俄勒冈大学贝克莱分校版本的
Unix,即人们所说的 BSD Unix。
因而,有时人们也把套接字称为“伯克利套接字”或“BSD
套接字”。一伊始,套接字被规划用在同
一台主机上多少个应用程序之间的简报。那也被称经过间通信,或
IPC。套接字有二种(可能叫做有多少个种族),分别是依据文件型的和依照互连网型的。 

依照文件类型的套接字家族

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,八个套接字进度运维在同一机器,能够由此走访同三个文件系统直接达成通讯

基于互连网项目标套接字家族

套接字家族的名字:AF_INET

(还有AF_INET6被用于ipv6,还有局地别的的地方家族,可是,他们或许是只用于有个别平台,要么正是现已被撇下,只怕是很少被接纳,或然是有史以来没有完成,全数地方家族中,AF_INET是应用最广大的一个,python帮衬很四种地点家族,但是由于大家只关注互连网编制程序,所以大多数时候小编么只利用AF_INET)

四 、套接字发展史及分类

套接字起源于 20 世纪 70 时代肯塔基大学Berkeley分校版本的
Unix,即人们所说的 BSD Unix。
因而,有时人们也把套接字称为“Berkeley套接字”或“BSD
套接字”。一开端,套接字被规划用在同
一台主机上三个应用程序之间的通信。那也被称经过间通信,或
IPC。套接字有二种(或许叫做有四个种族),分别是依照文件型的和依据互连网型的。 

 

2,完成文件传输

在后面包车型客车四个ssh做基础的地方下,大家是或不是也能跟ftp一样传文书这么些吗,当然能够毫无疑问的报告您,能够传文书的,而且在后边的学习实现之后,你还可以够协调写3个ftp完成上传下载文件的成效。先做一个简短的文件传输成效吗。

服务端(server)

澳门葡京备用网址 17澳门葡京备用网址 18

1 import socket,os
 2 server=socket.socket()
 3 server.bind(('127.0.0.1',1314))
 4 server.listen()
 5 while True:
 6     conn,addr=server.accept()
 7     print('连接成功!')
 8     try:
 9         while True:
10             file_name=conn.recv(1024).decode()
11             if not file_name: break
12             if os.path.isfile(file_name):#判断文件是否存在
13                 file_len=os.stat(file_name).st_size#获取文件大小
14                 conn.send(str(file_len).encode())
15                 conn.recv(1024)
16                 with open(file_name,'rb') as f:
17                     for i in f:
18                         conn.send(i)
19                 print('文件发送完成')
20             else:
21                 print('文件不存在')
22     except ConnectionResetError:
23         print('一个客户端断开')
24     finally:
25         conn.close()
26 server.close()

View Code

客户端(client)

澳门葡京备用网址 19澳门葡京备用网址 20

1 import socket
 2 client=socket.socket()
 3 client.connect(('127.0.0.1',1314))
 4 while True:
 5     file_name=input(">>>")
 6     if len(file_name)==0:continue
 7     client.send(file_name.encode())
 8     file_len=client.recv(1024).decode()
 9     client.send('接收数据长度成功'.encode())
10     get_len=0
11     f=open(file_name,'wb')
12     while get_len<float(file_len):
13         data=client.recv(1024)
14         get_len+=len(data)
15         f.write(data)
16         print('已经完成',get_len,'/',file_len)
17     print('文件传输完成')
18     f.close()
19 client.close()

View Code

五、基于TCP的socket

服务端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import subprocess
phone_server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone_server.bind(('192.168.16.40', 7082))
phone_server.listen(5)
print('server is run...')

while True:
    conn,client_addr = phone_server.accept()
    print('客户端:',client_addr)

    while True:
        try:
            cmd=conn.recv(1024)
            res=subprocess.Popen(cmd.decode('utf-8'),shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            stdout=res.stdout.read()
            stderr=res.stderr.read()

            conn.sendall(stdout+stderr)

        except Exception:
            break
    conn.close()

phone_server.close()

客户端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
phone_client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

phone_client.connect(('192.168.16.205',7082))

while True:
    cmd=input('>>:').strip()
    if not cmd:continue
    phone_client.send(cmd.encode('utf-8'))
    cmd_res = phone_client.recv(1024)
    # print(cmd_res.decode('gbk'))
    print(cmd_res.decode('utf-8'))

phone_client.close()

  

 

六 、套接字工作流程

       二个生活中的场景。你要打电话给多少个恋人,先拨号,朋友听到对讲机铃声后提起电话,那时你和您的心上人就建立起了再而三,就足以出口了。等交换甘休,挂断电话甘休此次交谈。 生活中的场景就分解了那工作原理。

澳门葡京备用网址 21 
    

                                           图3    
  

先从劳动器端说起。服务器端先起始化Socket,然后与端口绑定(bind),对端口实行监听(listen),调用accept阻塞,等待客户端连接。在此刻假诺有个客户端初步化多少个Socket,然后连接服务器(connect),借使老是成功,那时客户端与劳务器端的总是就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把应对数据发送给客户端,客户端读取数据,最终关闭连接,贰次交互甘休

socket()模块函数用法

服务端套接字函数
s.bind()    绑定(主机,端口号)到套接字
s.listen()  开始TCP监听
s.accept()  被动接受TCP客户的连接,(阻塞式)等待连接的到来

客户端套接字函数
s.connect()     主动初始化TCP服务器连接
s.connect_ex()  connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

公共用途的套接字函数
s.recv()            接收TCP数据
s.send()            发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
s.sendall()         发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
s.recvfrom()        接收UDP数据
s.sendto()          发送UDP数据
s.getpeername()     连接到当前套接字的远端的地址
s.getsockname()     当前套接字的地址
s.getsockopt()      返回指定套接字的参数
s.setsockopt()      设置指定套接字的参数
s.close()           关闭套接字

面向锁的套接字方法
s.setblocking()     设置套接字的阻塞与非阻塞模式
s.settimeout()      设置阻塞套接字操作的超时时间
s.gettimeout()      得到阻塞套接字操作的超时时间

面向文件的套接字的函数
s.fileno()          套接字的文件描述符
s.makefile()        创建一个与该套接字相关的文件

澳门葡京备用网址 22澳门葡京备用网址 23

import socket
ip_port=('自己电脑的IP',9000)  #电话卡
BUFSIZE=1024                #收发消息的尺寸
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
s.bind(ip_port) #手机插卡
s.listen(5)     #手机待机


conn,addr=s.accept()            #手机接电话
# print(conn)
# print(addr)
print('接到来自%s的电话' %addr[0])

msg=conn.recv(BUFSIZE)             #听消息,听话
print(msg,type(msg))

conn.send(msg.upper())          #发消息,说话

conn.close()                    #挂电话

s.close()                       #手机关机

服务端

澳门葡京备用网址 24澳门葡京备用网址 25

import socket
ip_port=('自己电脑的ip',9000)
BUFSIZE=1024
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.connect_ex(ip_port)           #拨电话

s.send('duoduo nb'.encode('utf-8'))         #发消息,说话(只能发送字节类型)

feedback=s.recv(BUFSIZE)                           #收消息,听话
print(feedback.decode('utf-8'))

s.close()                                       #挂电话

客户端

增加链接循环与通信循环

澳门葡京备用网址 26澳门葡京备用网址 27

import socket
ip_port=('IP地址',8081)#电话卡
BUFSIZE=1024
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
s.bind(ip_port) #手机插卡
s.listen(5)     #手机待机


while True:                         #新增接收链接循环,可以不停的接电话
    conn,addr=s.accept()            #手机接电话
    # print(conn)
    # print(addr)
    print('接到来自%s的电话' %addr[0])
    while True:                         #新增通信循环,可以不断的通信,收发消息
        msg=conn.recv(BUFSIZE)             #听消息,听话

        # if len(msg) == 0:break        #如果不加,那么正在链接的客户端突然断开,recv便不再阻塞,死循环发生

        print(msg,type(msg))

        conn.send(msg.upper())          #发消息,说话

    conn.close()                    #挂电话

s.close()                       #手机关机

优化服务端

澳门葡京备用网址 28澳门葡京备用网址 29

import socket
ip_port=('127.0.0.1',8081)
BUFSIZE=1024
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.connect_ex(ip_port)           #拨电话

while True:                             #新增通信循环,客户端可以不断发收消息
    msg=input('>>: ').strip()
    if len(msg) == 0:continue
    s.send(msg.encode('utf-8'))         #发消息,说话(只能发送字节类型)

    feedback=s.recv(BUFSIZE)                           #收消息,听话
    print(feedback.decode('utf-8'))

s.close()                                       #挂电话

优化客户端

 

① 、基于文件类型的套接字家族

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的正是底层的文件系统来取数据,三个套接字进程运维在同一机器,能够经过访问同叁个文件系统直接实现通讯

 

二,socketserver用法

前边都是为尾声面包车型地铁装逼做铺垫的,没错的,上边即将进入的是大家前几天的装逼操作了,socketserver。

本来那里我们也只是写不难的用法,其实用法跟socket用法是大半的,所以只给了简要的运用方法

服务端(server)

 1 import socketserver
 2 class MyServer(socketserver.BaseRequestHandler):
 3     def handle(self):#里面是跟客户端交互的全过程
 4         while True:
 5             try:
 6                 data=self.request.recv(1024) #self.request相当于socket里面的conn
 7                 print('收到来自客户端%s的消息:%s' %(self.request,data.decode()))
 8                 self.request.send(data.upper())
 9             except ConnectionResetError as e:
10                 print('error:',e)
11                 break
12 if __name__ == '__main__':
13     #创建一个服务,绑定ip跟端口
14     server=socketserver.ThreadingTCPServer(('127.0.0.1',1314),MyServer)
15     server.serve_forever()#服务一直开启

客户端(client)

1 import socket
2 client=socket.socket()
3 client.connect(('127.0.0.1',1314))
4 while True:
5     data=input('>>>')
6     client.send(data.encode())
7     get_data=client.recv(124)
8     print(get_data.decode())
9 client.close()

 

② 、基于互连网项目标套接字家族

套接字家族的名字:AF_INET

(还有AF_INET6被用来ipv6,还有一对别样的地方家族,可是,他们依旧是只用于有些平台,要么正是早已被遗弃,恐怕是很少被利用,或然是根本未曾达成,全数地方家族中,AF_INET是使用最普遍的1个,python支持很多种地方家族,不过出于大家只关切互联网编程,所以大多数时候小编么只利用AF_INET)

 

伍 、套接字工作流程

     
生活中的场景,你要打电话给3个情人,先拨号,朋友听到电话铃声后提起电话,那时你和您的心上人就确立起了连年,就可以说话了。等交换结束,挂断电话停止这次交谈。    

生存中的场景就分解了那工作规律,也许TCP/IP协议族正是诞生于生存中,那也不必然。

澳门葡京备用网址 30

socket例子:

1.服务端与客户端的平常通信。

澳门葡京备用网址 31澳门葡京备用网址 32

import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('really ==== go!!')

conn,client_addr=phone.accept()
print(conn,client_addr)

data=conn.recv(1024)
conn.send(data.upper())
print('client data:<%s>'%data)

conn.close()
phone.close()

服务端

澳门葡京备用网址 33澳门葡京备用网址 34

import socket

phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect  (('127.0.0.1',8080))

phone.send('hello'.encode('utf-8'))
data1 = phone.recv(1024)
print('server back res:<%s>'%data1)

phone.close()

客户端

首先:
服务端 先开始运行,等待接收,
之后,客户端运行,向服务端发送信息。

结果如下:
服务端:
really ==== go!!
<socket.socket fd=452, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 53789)> ('127.0.0.1', 53789)
client data:<b'hello'>

客户端:
server back res:<b'HELLO'>

客户端发了 hello  给服务端, 服务端收到信息,做了 大写化处理,返回给客户端。

2.服务端与客户端的正规通讯。socket通讯循环

澳门葡京备用网址 35澳门葡京备用网址 36

import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('really ==== go!!')

conn,client_addr=phone.accept()
print(conn,client_addr)

while True:  #通信循环
    data=conn.recv(1024)
    # print('server has recv')
    conn.send(data.upper())
    print('client data:<%s>'%data)

conn.close()
phone.close()

服务端

澳门葡京备用网址 37澳门葡京备用网址 38

import socket

phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect  (('127.0.0.1',8080))

while True:
    cmd = input('>>:').strip()
    if not cmd:continue     #如果cmd为空,继续发
    phone.send(cmd.encode('utf-8'))
    print('====> has send')
    data = phone.recv(1024)
    print('server back res:<%s>'%data)

phone.close()

客户端

首先:
这里比上一个例子,优化了,这里设置了input,可以自己输入。
添加了个循环,当客户端输入为空,不在报错,而是需要继续输入。

结果如下:
服务端:
really ==== go!!
<socket.socket fd=452, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 53865)> ('127.0.0.1', 53865)
client data:<b'1'>
client data:<b'2'>
client data:<b'3'>
client data:<b'a'>
client data:<b'b'>
client data:<b'c'>

客户端:
>>:1
====> has send
server back res:<b'1'>
>>:2
====> has send
server back res:<b'2'>
>>:3
====> has send
server back res:<b'3'>
>>:a
====> has send
server back res:<b'A'>
>>:b
====> has send
server back res:<b'B'>
>>:c
====> has send
server back res:<b'C'>

注意:
这里服务端在接到客户端的额信息是,只做了加大化吃力,所以把abc处理后为ABC返回给客户端。

3.服务端与客户端的例行通讯。socket链接循环。

澳门葡京备用网址 39澳门葡京备用网址 40

import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('really ==== go!!')
while True:  #链接循环
    conn,client_addr=phone.accept()
    print(conn,client_addr)

    while True:  #通信循环
        try:
            data=conn.recv(1024)
            # print('server has recv')
            conn.send(data.upper())
            print('client data:<%s>'%data)
        except Exception:
            break
    conn.close()
phone.close()

服务端

澳门葡京备用网址 41澳门葡京备用网址 42

import socket

phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect  (('127.0.0.1',8080))

while True:
    cmd = input('>>:').strip()
    if not cmd:continue     #如果cmd为空,继续发
    phone.send(cmd.encode('utf-8'))
    data = phone.recv(1024)
    print('server back res:<%s>'%data)
phone.close()

客户端1

澳门葡京备用网址 43澳门葡京备用网址 44

import socket

phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect  (('127.0.0.1',8080))

while True:
    cmd = input('>>:').strip()
    if not cmd:continue     #如果cmd为空,继续发
    phone.send(cmd.encode('utf-8'))
    print('====> has send')
    data = phone.recv(1024)
    print('server back res:<%s>'%data)

phone.close()

客户端2

首先,这里加的链接循环是为了防止,当我们有多个客户端时,
要关闭其中一个,而不导致整个程序出错。
在没做链接循环前,当我们关闭了其中一个客户端,服务端那里是不能在运行的。

输出结果:
服务端:
really ==== go!!
<socket.socket fd=384, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 53898)> ('127.0.0.1', 53898)
client data:<b'1'>
client data:<b'2'>
client data:<b'a'>
client data:<b'b'>
client data:<b'c'>
<socket.socket fd=384, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 53911)> ('127.0.0.1', 53911)
<socket.socket fd=384, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 53911)> ('127.0.0.1', 53911)
client data:<b'a'>
client data:<b's'>
client data:<b'd'>

客户端1:
>>:1
server back res:<b'1'>
>>:2
server back res:<b'2'>
>>:3
server back res:<b'3'>
>>:a
server back res:<b'A'>
>>:b
server back res:<b'B'>
>>:c
server back res:<b'C'>


客户端2:
>>:a
====> has send
server back res:<b'A'>
>>:s
====> has send
server back res:<b'S'>
>>:d
====> has send
server back res:<b'D'>

4.socket仿照ssh远程执行。

澳门葡京备用网址 45澳门葡京备用网址 46

import subprocess
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8081))
phone.listen(5)
print('really ==== go!!')
while True:  #链接循环
    conn,client_addr=phone.accept()
    print(conn,client_addr)

    while True:  #通信循环
        try:
            cmd=conn.recv(1080)
            if not cmd: break  #针对linux
            #执行cmd命令,拿到cmd的结果,结果应该是bytes类型
            #。。。
            #发送命令结果
            res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,  # 正确
                                   stderr=subprocess.PIPE  # 错误
                                   )
            stdout = res.stdout.read()
            stderr = res.stderr.read()
            conn.send(stdout+stderr)
        except Exception:
            break
    conn.close()
phone.close()

服务端

澳门葡京备用网址 47澳门葡京备用网址 48

import socket

phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect  (('127.0.0.1',8081))

while True:
    cmd = input('>>:').strip()
    if not cmd:continue     #如果cmd为空,继续发
    phone.send(cmd.encode('utf-8'))
    cmd_res = phone.recv(1080)
    print(cmd_res.decode('gbk'))
phone.close()

客户端

澳门葡京备用网址 49澳门葡京备用网址 50

说明:
1.客户端远程执行服务端。
2.登录的是windows系统,用的是‘gbk’ 编码。


服务端:
really ==== go!!
<socket.socket fd=400, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8081), raddr=('127.0.0.1', 53955)> ('127.0.0.1', 53955)


客户端:
>>:dir
 驱动器 E 中的卷没有标签。
 卷的序列号是 0001-0682

 E:\zbk\work_\work_8.21 socket模拟ssh远程执行 的目录

2017/08/21  19:25    <DIR>          .
2017/08/21  19:25    <DIR>          ..
2017/08/21  19:25               333 客户端1.py
2017/08/21  16:29               367 客户端2.py
2017/08/21  19:25               966 服务端2.py
2017/08/21  19:05               413 模块subprocess.py
               4 个文件          2,079 字节
               2 个目录 266,249,355,264 可用字节

>>:ipconfig /all

Windows IP 配置

   主机名  . . . . . . . . . . . . . : DESKTOP-0QR7V9H
   主 DNS 后缀 . . . . . . . . . . . : 
   节点类型  . . . . . . . . . . . . : 混合
   IP 路由已启用 . . . . . . . . . . : 否
   WINS 代理已启用 . . . . . . . . . : 否

以太网适配器 以太网:

   媒体状态  . . . . . . . . . . . . : 媒体已断开连接
   连接特定的 DNS 后缀 . . . . . . . : 
   描述. . . . . . . . . . . . . . . : Realtek PCIe GBE Family Controller
   物理地址. . . . . . . . . . . . . : 80-FA-5B-3C-8F-54
   DHCP 已启用 . . . . . . . . . . . : 是
   自动配置已启用. . . . . . . . . . : 是

无线局域网适配器 本地连接* 1:

   媒体状态  . . . . . . . . . . . . : 媒体已断开连接
   连接特定的 DNS 后缀 . . . . . . . : 
   描述. . . . . . . . . . . . . . . : Microsoft Wi-Fi Direct Virtual Adapter
   物理地址. . . . . . . . . . . . . : 70-1C-E7-32-BC-D5
   DHCP 已启用 . . . . . . . . . . . : 是
   自动配置已启用. . . . . . . . . . : 是

无线局域网适配器 WLAN:

   连接特定的 DNS 后缀 . . . . . . . : 
   描述. . . . . . . . . . . . . . . : Intel(R) Dual Band Wireless-
>>:

输出结果

5.socket  消除粘包难点。

澳门葡京备用网址 51澳门葡京备用网址 52

import struct
import subprocess
from socket import *

phone = socket(AF_INET,SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('ready go !!')

while True:
    conn,client.addr=phone.accept()
    print(conn,client_addr)
    while True:
        try:
        cmd = conn.recv(1024)
        if not cmd : break
        res = subprocess.Popen(cmd.decode('utf-8'),shell = True,
                                            stdout = stdout.subprocess.PIPE,
                                            stderr = stderr.subprocess.PIPE,)
        stdout  = res.stdout.read()
        stderr = res.stderr.read()
        header = struct.pack('i',len(stdout)+len(stderr))
        conn.send(header)
        conn.send(stdout)
        conn.send(stderr)
        except Exception:
            break
    conn.close()
phone.close()

服务端

澳门葡京备用网址 53澳门葡京备用网址 54

import struct
from socket import *

phone = socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',8080))

while True:
    cmd = input('>>:').strip()
    if not cmd : continue
    phone.send(cmd.encode('utf-8'))
    header_struct = phone.recv(4)
    unpack_res = struct.unpack('i',header_struct)
    total_size = unpack_res[0]
    total_data = b''
    recv_size = 0
    while recv_size < total_size:
        recv_data = phone.recv(1024)
        recv_size += len(recv_data)
        total_data += recv_data
    print(total_data.decode('gbk'))
phone.close()

客户端

 6.json 解决粘包难点。

澳门葡京备用网址 55澳门葡京备用网址 56

import socket
import subprocess
import struct
import json
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8082)) #绑定手机卡
phone.listen(5) #开机

print('starting...')
while True: #链接循环
    conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组)
    print('-------->',conn,client_addr)

    #收,发消息
    while True:#通信循环
        try:
            cmd=conn.recv(1024)
            if not cmd:break #针对linux
            #执行cmd命令,拿到cmd的结果,结果应该是bytes类型
            #。。。。
            res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            stdout=res.stdout.read()
            stderr=res.stderr.read()
            #制作报头
            header_dic = {
                'total_size': len(stdout)+len(stderr),
                'filename': None,
                'md5': None}

            header_json = json.dumps(header_dic)
            header_bytes = header_json.encode('utf-8')
            #发送阶段
            #先发报头长度
            conn.send(struct.pack('i',len(header_bytes)))
            #再发报头
            conn.send(header_bytes)

            #最后发送命令的结果
            conn.send(stdout)
            conn.send(stderr)
        except Exception:
            break
    conn.close() #挂电话
phone.close() #关机

服务端

澳门葡京备用网址 57澳门葡京备用网址 58

import socket
import struct
import json
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.connect(('127.0.0.1',8082)) #绑定手机卡

#发,收消息
while True:
    cmd=input('>>: ').strip()
    if not cmd:continue

    phone.send(cmd.encode('utf-8'))
    #先收报头的长度
    header_len=struct.unpack('i',phone.recv(4))[0]

    #再收报头
    header_bytes=phone.recv(header_len)
    header_json=header_bytes.decode('utf-8')
    header_dic=json.loads(header_json)
    total_size=header_dic['total_size']

    #最后收数据
    recv_size=0 #10241=10240+1
    total_data=b''
    while recv_size < total_size:
        recv_data=phone.recv(1024)
        recv_size+=len(recv_data)
        total_data+=recv_data
    print(total_data.decode('gbk'))
phone.close()

客户端

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website