一、osi七层
完整的计算机系统由硬件,操作系统,软件组成。
互联网的核心就是由一堆协议组成,协议就是标准,如全世界通信的标准就是英语。
如果把计算机比作人,那么互联网协议就是计算机界的英语,所有计算机都学会了互联网协议。那么所有计算机可以按照统一的标准去
收发信息从而完成通信
二、学习socket前一定先要学习互联网协议
三、socket
socket是基于应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口
socket类型
套接字格式
socket(family,type[,protocal]) 使用给定的地址族、套接字类型、协议编号(默认为0)来创建套接字。
socket类型 |
描述 |
socket.AF_UNIX |
只能够用于单一的Unix系统进程间通信 |
socket.AF_INET |
服务器之间网络通信 |
socket.AF_INET6 |
IPv6 |
socket.SOCK_STREAM |
流式socket , for TCP |
socket.SOCK_DGRAM |
数据报式socket , for UDP |
socket.SOCK_RAW |
原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。 |
socket.SOCK_SEQPACKET |
可靠的连续数据包服务 |
创建TCP Socket: |
|
创建UDP Socket: |
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
socket函数 |
描述 |
|
服务端socket函数 |
||
s.bind(address) |
将套接字绑定到地址, 在AF_INET下,以元组(host,port)的形式表示地址. |
|
s.listen(backlog) |
开始监听TCP传入连接。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 |
|
s.accept() |
接受TCP连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。 |
|
客户端socket函数 |
||
s.connect(address) |
连接到address处的套接字。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 |
|
s.connect_ex(adddress) |
功能与connect(address)相同,但是成功返回0,失败返回errno的值。 |
|
公共socket函数 |
||
s.recv(bufsize[,flag]) |
接受TCP套接字的数据。数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 |
|
s.send(string[,flag]) |
发送TCP数据。将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 |
四、socket编程之服务端代码
1.简单套接字:
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.bind(('192.168.20.60',8080)) #绑定手机卡 phone.listen(5) #开机 print('starting...') conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组) print(conn,client_addr) #收,发消息 data=conn.recv(1024) print('client data: <%s>' %data) conn.send(data.upper()) conn.close() #挂电话 phone.close() #关机
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.connect(('192.168.20.60',8080)) #绑定手机卡 #发,收消息 phone.send('hello'.encode('utf-8')) data=phone.recv(1024) print('server back res:<%s>' %data) phone.close()
2、加上通信循环
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 phone.bind(('192.168.20.60',8081)) #绑定手机卡 phone.listen(5) #开机 print('starting...') conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组) print('-------->',conn,client_addr) #收,发消息 while True:#通信循环 data=conn.recv(1024) # print('server has recv') print('client data: <%s>' %data) conn.send(data.upper()) conn.close() #挂电话 phone.close() #关机
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.connect(('192.168.20.60',8081)) #绑定手机卡 #发,收消息 while True: msg=input('>>: ').strip() if not msg:continue phone.send(msg.encode('utf-8')) print('--->has send') data=phone.recv(1024) print('server back res:<%s>' %data) phone.close()
3.加上链接循环
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 phone.bind(('192.168.20.60',8081)) #绑定手机卡 phone.listen(5) #开机 print('starting...') while True: #链接循环 conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组) print('-------->',conn,client_addr) #收,发消息 while True:#通信循环 try: data=conn.recv(1024) if not data:break #针对linux print('client data: <%s>' %data) conn.send(data.upper()) except Exception: break conn.close() #挂电话 phone.close() #关机
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.connect(('192.168.20.60',8081)) #绑定手机卡 #发,收消息 while True: msg=input('>>: ').strip() if not msg:continue phone.send(msg.encode('utf-8')) data=phone.recv(1024) print('server back res:<%s>' %data) phone.close()
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.connect(('192.168.20.60',8081)) #绑定手机卡 #发,收消息 while True: msg=input('>>: ').strip() if not msg:continue phone.send(msg.encode('utf-8')) data=phone.recv(1024) print('server back res:<%s>' %data) phone.close()
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.connect(('192.168.20.60',8081)) #绑定手机卡 #发,收消息 while True: msg=input('>>: ').strip() if not msg:continue phone.send(msg.encode('utf-8')) data=phone.recv(1024) print('server back res:<%s>' %data) phone.close()
4、模拟ssh远程执行命令
import socket import subprocess phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 phone.bind(('192.168.20.60',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() #发送命令的结果 conn.send(stdout+stderr) except Exception: break conn.close() #挂电话 phone.close() #关机
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.connect(('192.168.20.60',8082)) #绑定手机卡 #发,收消息 while True: cmd=input('>>: ').strip() print(cmd) if not cmd:continue phone.send(cmd.encode('utf-8')) cmd_res=phone.recv(1024) print(cmd_res.decode('gbk')) phone.close()
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.connect(('192.168.20.93',8082)) #绑定手机卡 #发,收消息 while True: msg=input('>>: ').strip() if not msg:continue phone.send(msg.encode('utf-8')) data=phone.recv(1024) print('server back res:<%s>' %data) phone.close()
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.connect(('192.168.20.93',8082)) #绑定手机卡 #发,收消息 while True: msg=input('>>: ').strip() if not msg:continue phone.send(msg.encode('utf-8')) data=phone.recv(1024) print('server back res:<%s>' %data) phone.close()
import subprocess res=subprocess.Popen(r'dirasdf',shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print(res.stdout.read().decode('gbk')) print('==========================') # print(res.stdout.read()) print(res.stderr.read().decode('gbk'))