网络编程其他篇

目录:

1.1 socket理论部分返回顶部

  1、socket起源

      1. socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。

      2. socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

      3. 基本上,Socket 是任何一种计算机网络通讯中最基础的内容

      4. 例如当你在浏览器地址栏中输入 http://www.cnblogs.com/ 时,你会打开一个套接字,然后连接到 http://www.cnblogs.com/ 并读取响应的页面然后然后显示出来

      5. socket和file的区别:

        1)  file模块是针对某个指定文件进行【打开】【读写】【关闭】

        2)  socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】

  2、socket.socket( family, type )  实例化一个socket类

    1. 实例化需要3个参数

        1)  第一个是地址簇(默认是socket.AF_INET)

        2)  第二个是流(socket.SOCK_STREAM, 默认值)或数据报(socket.SOCK_DGRAM)套接字

        3)  第三个是实用的协议(默认是0 使用默认即可),对于一个普通的套接字不需要提供任何参数

    2. 第一个参数:  Socket Families(地址簇)  类似于OSI七层的网络层

        1socket.AF_UNIX     unix本机进程间通信(本机没有网卡时本机件进程自己起socket通信)

        2)socket.AF_INET   IPV4 

        3)socket.AF_INET6  IPV6

    3. 第二个参数:  Socket Families(地址簇)  类似于OSI七层的传输层

        1)socket.SOCK_STREAM   #for tcp

        2)socket.SOCK_DGRAM    #for udp

        3)socket.SOCK_RAW    #原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;

            其次,SOCK_RAW也可以处理特殊的IPv4报文;此外利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头

        4)socket.SOCK_RDM    #是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议低级访问,

            在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用

  3、socket对象可以使用的所有方法

# 1、 sk.bind(address)
   s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。 # 2、 sk.listen(backlog)
   开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。
backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5
这个值不能无限大,因为要在内核中维护连接队列 # 3、 sk.setblocking(bool)
   是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。 # 4、 sk.accept()
   接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。
   接收TCP 客户的连接(阻塞式)等待连接的到来 # 5、 sk.connect(address)
   连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 # 6、 sk.connect_ex(address)
   同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061 # 7、 sk.close()
   关闭套接字 # 8、 sk.recv(bufsize[,flag])
   接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。 # 9、 sk.recvfrom(bufsize[.flag])
   与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 # 10、 sk.send(string[,flag])
   将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。 # 11、 sk.sendall(string[,flag])
   将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
内部通过递归调用send,将所有内容发送出去。 # 12、 sk.sendto(string[,flag],address)
   将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。 # 13、 sk.settimeout(timeout)
   设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s ) # 14、 sk.getpeername()
   返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 # 15、 sk.getsockname()
   返回套接字自己的地址。通常是一个元组(ipaddr,port) # 16、 sk.fileno()
   套接字的文件描述符

socket对象可以使用的所有方法总结

  4、TCP三层握手

####1、第一次握手
# 建立连接时,客户端发送SYN包到服务器,其中包含客户端的初始序号seq=x,并进入SYN_SENT状态,等待服务器确认。 ####2、第二次握手
# 服务器收到请求后,必须确认客户的数据包。同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN_RECV状态。 ####3、第三次握手
# 客户端收到服务器的SYN+ACK包,向服务器发送一个序列号(seq=x+1),确认号为ack(客户端)=y+1,此包发送完毕,
# 客户端和服务器进入ESTAB_LISHED(TCP连接成功)状态,完成三次握手。

三次握手

#### 1、第一次挥手
# 首先,客户端发送一个FIN,用来关闭客户端到服务器的数据传送,然后等待服务器的确认。其中终止标志位FIN=1,序列号seq=u。 #### 2、第二次挥手
# 服务器收到这个FIN,它发送一个ACK,确认ack为收到的序号加一。 #### 3、第三次挥手
# 关闭服务器到客户端的连接,发送一个FIN给客户端。 #### 4、第四次挥手
# 客户端收到FIN后,并发回一个ACK报文确认,并将确认序号seq设置为收到序号加一。
# 首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

四次挥手

    

1.2 socket处理单个连接 和 同时接受多个连接返回顶部

  1、socket通信原理图解

  2、简单的socket列子:处理单个连接

import socket
#服务器端
server = socket.socket() # 创建一个socket对象
server.bind(('',6969)) # host=’ ‘或者‘0.0.0.0’都表示所有计算机都可以访问服务器
server.listen() # server.listen(5) 表示同时可以有五个客户连接到服务器 conn,addr = server.accept() # c, addr = s.accept() 这是一种赋变量的方法,会组成一个元组。
# 代表只要客户端提供地址(addr)就可以接受外部的链接
data = conn.recv(1024) # 收到客户端数据:recv默认是阻塞的,收到数据为空则死循环
conn.send(data.upper()) # 服务器返回数据给client端 server.close()

处理单个连接: server部分

import socket
#客户端
client = socket.socket() # 创建socket对象
client.connect(('localhost',6969)) # 连接到服务端
client.send("在python3中socket仅可以传送byte类型".encode("utf-8")) # 发送数据到服务端
data = client.recv(1024) # 接收服务端返回数据 print('客户端收到返回数据为:',data.decode())
client.close()

处理单个连接: client部分

  3、socket实现同时连接多个客户端

      1. 这里仅能实现,同时连接多个客户端,但同一时刻仅能有一个客户端与服务的通信,其他客户端阻塞状态

      2. 只有当前一个客户端断开连接后,后面的客户端才能与服务端发消息

      3. 经测试,只能在Linux服务器中实现,在Windows中,断开客户端后服务端就会应发异常

#-*- coding:utf-8 -*-
import socket
#服务器端python3.5 server = socket.socket()
server.bind(('',6969)) #绑定要监听的端口
server.listen(5) #我要监听这个端口,最大连接数为:5
print("我要开始等电话了")
while True: #当一个客户端断开后程序就回到这里,等待下一个连接
conn,addr = server.accept() #等电话打进来 conn是打电话实例,addr电话号码
#conn就是客户端连过来而在服务器端为其生成的连接实例,这里其实就是为每个客户端生成一个实例区分
while True:
data = conn.recv(1024) #data是接收到的从客户端发送过来的数据
print("rect:",data) #将客户端发送过来的数据在服务器端打印
if not data:
#如果客户端断开连接,data就为空,就跳出内层while循环,到达外层循环等待下一个客户端连接
print("host has lost!!!")
break
conn.send(data.upper()) #将客户端发送来的数据变成大写,然后再发送给客户端
server.close()

同时连接多个客户端server端代码

#-*- coding:utf-8 -*-
import socket
#客户端python3.5 client = socket.socket() #声明socket类型,同时生成socket连接对象
client.connect(('1.1.1.3',6969)) #指定要连接的服务器地址和端口号 while True:
msg = input(">>:").strip() #输入要发送给服务器的消息
if len(msg) == 0:continue #如果客户端输入空格,让客户端继续输入
client.send(msg.encode("utf-8")) #将输入的消息发送到服务器端
data = client.recv(1024) #接收服务器端发送过来的数据,每次1024字节
print('client_recv:',data) #将从服务器端接收的数据在客户端打印出来
client.close()

同时连接多个客户端client端代码

1.3 socket实现远程执行命令,下载文件返回顶部

   1、使用socket实现远程执行命令

#-*- coding:utf-8 -*-
import socket,os #服务器端python3.5
server = socket.socket()
server.bind(('1.1.1.3',6969)) #绑定要监听的端口
server.listen(5) #我要监听这个端口
print("我要开始等电话了")
while True:
conn,addr = server.accept() #等电话打进来 conn是打电话实例,addr电话号码
while True:
#conn就是客户端连过来而在服务器端为其生成的连接实例
data = conn.recv(1024)
data = data.decode()
print("接收的命令:",data)
if not data:
print("host has lost!!!")
break
res = os.popen(data).read()
conn.send(res.encode("utf-8"))
server.close()

执行命令: server端

#-*- coding:utf-8 -*-
import socket
#客户端python3.5
client = socket.socket() #声明socket类型,同时生成socket连接对象
client.connect(('1.1.1.3',6969)) while True:
msg = input(">>:").strip()
client.send(msg.encode("utf-8"))
data = client.recv(1024) print('客户端接收到服务端命令结果:',data.decode())
client.close()

执行命令: client端

  2、 socket实现下载文件

      1)先在服务器上把要传送的视屏文件打开,用send发送给客户端
      2)在客户端上打开一个新文件,将收到数据写入到文件中
      3)测试结果是:在客户端每次输入任意符号服务器端就会发送一个1024字节的文件到客户端
      4)可以看到的结果是,文件以1024的倍数增加

import socket,os
#socket服务器端
server = socket.socket()
server.bind(('0.0.0.0',2222))
server.listen(5)
while True:
conn,addr = server.accept()
while True:
file_name = conn.recv(1024).decode()
file_size = os.stat(file_name).st_size
conn.send(str(file_size).encode("utf-8"))
with open(file_name,'rb') as f:
for line in f:
conn.send(line)
server.close()

socket下载文件: server端

import  socket
#socket客户端
client = socket.socket()
client.connect(('1.1.1.3',2222))
while True:
file_name = input("please input you need to download file:")
client.send(file_name.encode("utf-8"))
file_size = client.recv(1024).decode()
print(type(file_size),file_size)
file_size = int(file_size)
recv_size = 0
with open(file_name + '.new','wb') as f:
while recv_size < file_size:
data = client.recv(1024)
f.write(data)
recv_size += 1024
client.close()

socket下载文件: client端代码

1.4 通过socket实现简单的ssh 和 处理连包问题返回顶部

   1、说明

      1. 先运行服务器端,再运行客户端,客户端连接后发送数据给服务器端,服务器端将结果返回给客户端
      2. 这段代码在windows python3.5中运行和 centos6.5系统中运行都正常
      3. 下面用Windows作为客户端,centos6.5作为服务器端演示操作结果
      4. 运行发现如果客户端服务端都在centos中运行时,客户端断开服务器端会继续监听下一个连接
      5. 但是如果客户端是Windows无论服务器端是什么系统客户端断开服务器端就会自动断开

   2、socket实现ssh远程执行命令 及 处理连包问题

import socket,os
#ssh服务器端代码 server = socket.socket()
server.bind(('0.0.0.0',9999)) #0.0.0.0表示允许所有主机连接
server.listen()
print("服务器端ssh开始监听客户端的链接啦!!") while True:
conn,addr = server.accept() #每次客户端断开,就会到这里等待新的连接
while True:
print("等待新指令!!")
client_cmd = conn.recv(1024).decode() #服务器端接收客户端发送过来的命令
if not client_cmd: #1 如果客户端断开连接收到的数据为空就会卡在这里
print("客户端已断开连接")
break
print("执行命令:",client_cmd)
cmd_res = os.popen(client_cmd).read() #接收字符串,执行结果也是字符串
print("before send:",len(cmd_res)) #打印出命令执行结果的长度
if len(cmd_res) == 0: #2 如果命令错误则执行结果长度为 0
cmd_res = "The command is wrong!!"
conn.send( str(len(cmd_res.encode())).encode("utf-8") ) #发送命令结果长度
client_ack = conn.recv(1024) #3 为了解决连包问题可以在两个send中间加一个recv
conn.send(cmd_res.encode("utf-8")) #将命令执行结果发送给客户端
print("send done")
server.close()

ssh服务器: server端代码

import socket
#ssh 客户端程序代码 client = socket.socket()
client.connect(('localhost',9999)) while True:
cmd = input("请输入要执行的命令:")
if len(cmd) == 0:continue #1 客户端输入命令为空就不发送让他继续输入命令
client.send(cmd.encode("utf-8")) #将要执行命令发送到服务器
cmd_res_size = client.recv(1024).decode() #接收命令结果的长度
print("执行命令结果的长度:",cmd_res_size) #打印要接收结果的数据长度
client.send('ok'.encode('utf-8')) #2 为解决连包问题可以在连续两次send中间加一个recv
received_size = 0 #接收数据的长度初始值为 0
received_data = b'' #接收到的数据初始值为 空字符串
while received_size < int(cmd_res_size):
data = client.recv(1024) #每次从服务器端接收1024的数据
received_size += len(data) #接收到的数据长度累加
received_data += data #每次接收的数据累加到 received_data变量中
else:
print("The command receive done:",received_size) #打印最终接收的长度
print(received_data.decode()) #将接收到的命令执行结果打印出来
client.close() #1 在centos6.5 10.1.0.50服务器端运行结果:
[root@localhost python]# python35 ssh_server.sh
服务器端ssh开始监听客户端的链接啦!!
等待新指令!!
执行命令: df
before send: 429
send done
等待新指令!!
#2 在Windows 7中运行客户端的结果:
请输入要执行的命令:df
执行命令结果的长度: 429
The command receive done: 429
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup-lv_root 38744716 4118012 32658576 12% /
tmpfs 510148 224 509924 1% /dev/shm
/dev/sda1 495844 34846 435398 8% /boot
/dev/sr0 4363088 4363088 0 100% /media/CentOS_6.5_Final
/dev/sr0 4363088 4363088 0 100% /mnt

ssh 客户端: client端代码

01: socket模块的更多相关文章

  1. socket编程--socket模块介绍

    socket也称作'套接字,用于描述IP地址和端口,是一个通信的终点. socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",对于文件用[打开][读写] ...

  2. Python中的socket 模块

    Python 提供了两个基本的 socket 模块.第一个是 Socket,它提供了标准的 BSD Sockets API.第二个是 SocketServer, 它提供了服务器中心类,可以简化网络服务 ...

  3. Python网络编程(2)——socket模块(2)

    目录: 1. 异常 2. 地址族 3. 套接字类型 4. 模块方法 5. Socket对象与实例方法 socket模块提供了Python中的低层网络连接接口,用于操作套接字操作. 异常 socket模 ...

  4. 第五十五节,IO多路复用select模块加socket模块,伪多线并发

    IO多路复用select模块加socket模块,伪多线并发,并不是真正的多线程并发,实际通过循环等待还是一个一个处理的 IO多路复用,lo就是文件或数据的输入输出,IO多路复用就是可以多用户操作 IO ...

  5. 第五十三节,socket模块介绍,socket单线程通讯

    socket单线程通讯,只能单线程通讯,不能并发 socket是基于(TCP.UDP.IP)的通讯.也叫做套接字 通讯过程由服务端的socket处理信息发送,由客户端的socket处理信息接收. so ...

  6. 老李分享:使用 Python 的 Socket 模块开发 UDP 扫描工具

    老李分享:使用 Python 的 Socket 模块开发 UDP 扫描工具 poptest是业内唯一的测试开发工程师培训机构,测试开发工程师主要是为测试服务开发测试工具,在工作中要求你做网络级别的安全 ...

  7. python实战第一天-socket模块练习

    操作系统 Ubuntu 15.10 IDE & editor JetBrains PyCharm 5.0.2 ipython3 Python版本 python-3.4.3 导入socket模块 ...

  8. python学习记录-socket模块

    主要使用的模块是socket模块,在这个模块中可以找到socket()函数,该函数用于创建套接字对象.套接字也有自己的方法集,这些方法可以实现基于套接字的网络通信. 1.socket类型 构造函数: ...

  9. 网络协议,socket模块

    """网络通讯要素:1.物理介质2.通讯协议 osi五层模型 应用层 传输层 网络层 数据链路层 物理层 物理层能传输010101二进制单纯的二进制是没有意义的,必须得知 ...

随机推荐

  1. opengl学习笔记(三):经过纹理贴图的棋盘

    opengl纹理贴图的步骤: 1:创建纹理对象,并为它指定一个纹理 2:确定纹理如何应用到每个像素上 3:启用纹理贴图功能 4:绘制场景,提供纹理坐标和几何图形坐标 注意:纹理坐标必须在RGBA模式下 ...

  2. Linux上Oracle 11g安装步骤图解

    Oracle 11g下载地址: http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 选 ...

  3. JSON Web Token – 在 Web 应用间安全地传递信息

    出处:子回 使用 JWT 令牌和 Spring Security 来实现身份验证 八幅漫画理解使用JSON Web Token设计单点登录系统

  4. 易忘的mysql语句

    1.修改主键 ALTER TABLE `resource` DROP PRIMARY KEY ,ADD PRIMARY KEY ( `rid` ) 2.加上auto_increment ) NOT N ...

  5. 配合dedecms内容模型实现后台输入栏目id前端输出文章列表

    为了简化开发的工作量,也方便编辑快速操作,决定将后台进行重新设置.配合dedecms内容模型实现后台输入栏目id前端输出文章列表,这样制作科室专题页也变快了很多.比如,我们添加一个“科室专家栏目id” ...

  6. 显示界面的流畅性FHHFPSIndicator

    github地址https://github.com/jvjishou/FHHFPSIndicator 1.使用cocoapods  pod 'FHHFPSIndicator' 使用方法: 然后在Ap ...

  7. [LeetCode] 181. Employees Earning More Than Their Managers_Easy tag: SQL

    The Employee table holds all employees including their managers. Every employee has an Id, and there ...

  8. git 下载单个文件 已经添加多个远程服务器

    175down vote It is possible to do (in the deployed repository) git fetch followed by git checkout or ...

  9. NLP总览

    一.自然语言处理概述 1)自然语言处理:利用计算机为工具,对书面实行或者口头形式进行各种各样的处理和加工的技术,是研究人与人交际中以及人与计算机交际中的演员问题的一门学科,是人工智能的主要内容. 2) ...

  10. H2O.ai初步使用

    1.官网下载最新稳定版,https://www.h2o.ai/download/ ,如果点击下载无反应,请使用ie浏览器 2.解压h2o-3.18.0.10.zip到目录h2o-3.18.0.10 3 ...