网络编程

网络编程 
什么socket?

TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。
使用TCP的应用:Web浏览器;电子邮件、文件传输程序。

UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大
努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
   
软件
客户端:CS架构, client -> server
浏览器:BS架构, browser -> server

为什么要网络通信发送的是字节?而不是字符串?
py3, send/recv 都是字节
py2, send/recv 都是字符串


服务端:
accept,阻塞:等待客户端来连接。
recv, 阻塞:等待客户端发来数据。

客户端:
connect,阻塞:一直在连接,直到连接成功才往下运行其他代码。
recv, 阻塞:等待服务端发来数据。

服务端:
 1 import socket
 2 
 3 server = socket.socket()
 4 
 5 server.bind(('127.0.0.1',8001))
 6 
 7 server.listen(5)
 8 
 9 while True:
10     conn,addr = server.accept()
11     # 字节类型
12     try:
13         while True:
14             data = conn.recv(1024) # 阻塞
15             if data == b'exit':
16                 break
17             response = data + b' SB'
18             conn.send(response)
19     except ConnectionResetError:#防止客户端终端后 服务端异常  window环境下使用
20         break
21 
22     conn.close()

客户端:

 1 import socket
 2 
 3 sk = socket.socket()
 4 
 5 sk.connect(('127.0.0.1',8001))
 6 
 7 while True:
 8     name = input("请输入姓名:")
 9     sk.send(name.encode('utf-8')) # 字节
10 
11     if name == 'exit':
12         break
13 
14     response = sk.recv(1024) # 字节
15     print(response.decode('utf-8'))
16 
17 sk.close()

 

 

socket粘包

socket的粘包为在数据量小与时间间隔短的情况下 优化算法使数据减少IO以达到提高效率,减少网络IO的一种方式

socket下的send与recv并不是一对一的  可以一对多 多对一即可  

粘包主要是接收端不知所接收的大小(即不知数据的开头与结尾)  只要明确数据的大小 即可解决粘包导致的缺点 

一般可以使用struck来达到效果

 

send  : 只需要copy data     send不是直接操作网卡的   本质上是数据由用户程序copy到操作系统缓存    操作系统来调用网卡传输     

recv: 1. wait data   2. copy data  时间较长   

 

struct用法

 1 import struct
 2 res=struct.pack("i","")
 3 print(res)
 4 print(len(res))
 5 obj=struct.unpack("i",res)
 6 print(obj[0])import struct
 7 res=struct.pack("i","")
 8 print(res)
 9 print(len(res))
10 obj=struct.unpack("i",res)
11 print(obj[0])
struct

subprocess用法

import subprocess

res=subprocess.Popen("dir",
                     shell=True,
                     stderr=subprocess.PIPE,
                     stdout=subprocess.PIPE)
print(res.stdout.read().decode("gbk"))
subprocess

 

SSH Server

 1 import socket
 2 import subprocess
 3 
 4 server = socket.socket()
 5 
 6 server.bind(('127.0.0.1',8008))
 7 
 8 server.listen(5)
 9 
10 while True:
11     print("server is working.....")
12     conn,addr = server.accept()
13     # 字节类型
14     while True:
15         # 针对window系统
16 
17         try:
18             cmd = conn.recv(1024).decode("utf8") # 阻塞
19             if cmd.encode("utf-8") == b'exit':
20                 break
21             res=subprocess.Popen(cmd,
22                              shell=True,
23                              stderr=subprocess.PIPE,
24                              stdout=subprocess.PIPE,
25                              )
26             # print("stdout",res.stdout.read())
27             # print("stderr",res.stderr.read().decode("gbk"))
28             out=res.stdout.read()
29             err=res.stderr.read()
30 
31             print("out响应长度",len(out))
32             print("err响应长度",len(err))
33             if err:
34                  import struct
35                  header_pack = struct.pack("i", len(err))
36                  conn.send(header_pack)
37                  conn.send(err)
38             else:
39                  #构建报头
40                  import struct
41                  header_pack=struct.pack("i",len(out))
42                  print("header_pack",header_pack)
43                  # # 发送报头
44                  conn.send(header_pack)
45                  # 发送数据
46                  conn.send(out)
47 
48         except Exception as e:
49             break
50 
51 
52     conn.close()
View Code

 

SSH Client

 1 import socket
 2 import struct
 3 sk = socket.socket()
 4 
 5 sk.connect(('127.0.0.1',8008))
 6 
 7 while 1:
 8     cmd = input("请输入命令:")
 9     sk.send(cmd.encode('utf-8')) # 字节
10     if cmd=="":
11         continue
12     if cmd == 'exit':
13         break
14 
15     header_pack=sk.recv(4)
16     data_length=struct.unpack("i",header_pack)[0]
17     print("data_length",data_length)
18     '''
19     b'xxx/xxx/xxx/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
20 
21 
22     '''
23 
24     recv_data_length=0
25     recv_data=b""
26 
27     while recv_data_length<data_length:
28         data=sk.recv(1024)
29         recv_data_length+=len(data)
30         recv_data+=data
31 
32     print(recv_data.decode("gbk"))
33 
34 
35 sk.close()
View Code

 

socketserver可以实现并发的网络通信

server

 1 import socketserver
 2 
 3 class Myserver(socketserver.BaseRequestHandler):
 4     def handle(self):# handel之内的逻辑由程序员编写,request等同于socket对象conn
 5         # 字节类型
 6         while 1:
 7             # 针对window系统
 8             try:
 9                 print("等待信息")
10                 data = self.request.recv(1024)  # 阻塞
11                 # 针对linux
12                 if len(data) == 0:
13                     break
14                 if data == b'exit':
15                     break
16                 response = data + b'SB'
17                 self.request.send(response)
18             except Exception as e:
19                 break
20 
21         self.request.close()
22 
23 
24 # 1 创建socket对象 2 self.socket.bind()  3 self.socket.listen(5)
25 # server=socketserver.ForkingUDPServer(("127.0.0.1",8899),Myserver)
26 server=socketserver.ThreadingTCPServer(("127.0.0.1",8899),Myserver) # socket建立,bind,listen方法
27 
28 server.serve_forever()#类似于accept方法

 client

 1 import socket
 2 
 3 sk = socket.socket()
 4 
 5 sk.connect(('127.0.0.1',8899))
 6 
 7 while 1:
 8     name = input(">>>>:")
 9     sk.send(name.encode('utf-8')) # 字节
10 
11     response = sk.recv(1024) # 字节
12     print(response.decode('utf-8'))

 

posted on 2020-12-04 08:38  随风~旋  阅读(110)  评论(0编辑  收藏  举报

导航