1 网络通信要素

  OSI模型定义不同计算机互联网的标准,设计和描述计算机网络通信的基本框架。

  1)IP地址:用来表示网络上一台独立的主机;IP地址=网络地址+主机地址;特殊IP地址:127.0.0.1(本地回环地址,保留地址,点份十进制)。

  2)端口号:要将数据发送到对方的指定的应用程序上,为了表示这些应用程序,所有这些网络应用程序都用数字进行标识,为了方便称呼这些数字,则将这些数字称为端口。

  3)传送协议:通讯的规则,例如:TCP,UDP协议(好比两个人用统一中国语言进行交流)。

2 网络通讯步骤

  确定对方IP地址->确定应用程序端口->确定通讯协议

  网络通讯的过程其实就是一个(源端)不断的封装数据包(目的端)不断拆数据包的过程。

3 通信的方法

  server下的方法

    sk.accept()接收的是客户端的sk相关信息,返回信息类型为元组。

    bind()

    listen()

    send()

    sendall()

    recv()

    close(),关通道与关服务器是不同的。关通道不影响其它通道。

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socket
 2 
 3 # family=AF_INET是指定使用何种的地址类型,ADDRESS FAMILY是地址族,INET:internetwork。
 4 # type确定设置通信的协议类型,SOCK_SREAM。
 5 sk = socket.socket()
 6 print(sk)
 7 # 绑定IP地址
 8 address = ('127.0.0.1', 8000)
 9 sk.bind(address)
10 sk.listen(3)  # 确定连接的最大数量
11 print("waitting...")
12 # conn就是通道,所有的数据连接都是通过conn连接。
13 conn, addr = sk.accept()  # 创建连接
14 inp = input("请输入")
15 conn.send(bytes(inp, 'utf-8'))  # 传送的类型是bytes类型

服务端

  client下的方法

    listen()

    recv()

    send()

    close()

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socket
 2 
 3 # 不需要绑定,直接绑定
 4 sk = socket.socket()
 5 address = ('127.0.0.1', 8000)
 6 sk.connect(address)
 7 
 8 data = sk.recv(1024) # 一次最大接收多少
 9 print(str(data, 'utf-8'))  # 如果接受是汉字,需要进行编码
10 
11 # 只关闭自己的通道,其它的对象没有关系
12 sk.close()

客户端

4 实际应用聊天

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socket
 2 
 3 sk = socket.socket()
 4 print(sk)
 5 address = ('127.0.0.1', 8000)
 6 sk.bind(address)
 7 sk.listen(3)  # 最大排队数,排队数量为3个。
 8 print("waitting...")
 9 # conn, addr = sk.accept() # 此处也可增加一个while循环。
10 
11 
12 while 1:
13     conn, addr = sk.accept()
14     print(addr)
15     while True:
16         try:
17             data = conn.recv(1024)  # 此处异常关闭客户端会出现异常
18         except Exception as e:
19             print(e)
20             break  # 跳出里层的循环
21         if not data:
22             break
23         inp = input("请输入")
24         conn.send(bytes(inp, 'utf-8'))  # 传送的类型是bytes类型
25 
26 conn.close()

server

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socket
 2 
 3 # 不需要绑定,直接绑定
 4 sk = socket.socket()
 5 address = ('127.0.0.1', 8000)
 6 sk.connect(address)
 7 
 8 while True:
 9     inp = input('>>>')
10     if inp == "exit":
11         break
12     sk.send(bytes(inp, 'utf-8')) # 不能发空
13 
14     data = sk.recv(1024) # 一次最大接收多少
15     print(str(data, 'utf-8'))  # 如果接受是汉字,需要进行编码
16 sk.close()

client

 5 远程执行命令

  编码:从明文到编码文本的转换过程叫做编码。

  解码:从编码文本到明文的转换过程叫做解码。

  Python2的string编码

    在Python2中,有两种字符串类型:str类型和unicode类型;注意,这仅仅是两个名字,python定义的两个名字,关键是这两种数据类型在程序运行时存在内存地址的是什么?内置函数repr可以帮我们在这里显示存储内容。原来,str和unicode分别存的是字节数据和unicode数据。

  Python3的string编码

    Python3也有两种数据类型:str和bytes;  str类型存unicode数据,bytse类型存bytes数据,与py2比只是换了一下名字而已

  文件从磁盘到内存的编码

    例如在文本编辑器word上编辑文字的时候,在保存数据之前通过unicode的形式存在内存中,当保存到磁盘上时通过某种编码方式编码成bytes字节串,例如utf-8等,

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 s = 'hello 袁浩'  # uicode万国码,在哪个国家都是相同的
 2 print(type(s))  # <class 'str'>
 3 
 4 # 由str到bytes:编码
 5 b1 = bytes(s, 'utf-8')
 6 print("b1", b1)  # b'hello \xe8\xa2\x81\xe6\xb5\xa9'  UTF-8规则下的bytes类型
 7 b2 = s.encode('utf-8')  # encode()是编码,有看到的数字转化为utf-8的数字
 8 print("b2", b2)
 9 b3 = s.encode('gbk')
10 print("b3", b3)
11 
12 
13 # 由bytes到str:解码
14 s1 = str(b2, 'utf-8')  # 解码的一种方式
15 print('s1', s1)
16 s2 = b2.decode('utf-8')
17 print('s2', s2)
18 s3 = b3.decode('gbk')
19 print('s3', s3)
20 
21 
22 # cmd_result = obj.stdout.read()  # 数据类型为gbk,Windows下自动转成gbk

编码和解码的操作

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socket
 2 import subprocess
 3 
 4 sk = socket.socket()
 5 print(sk)
 6 address = ('127.0.0.1', 8000)
 7 sk.bind(address)
 8 sk.listen(3)  # 最大排队数,排队数量为3个。
 9 print("waitting...")
10 
11 while 1:
12     conn, addr = sk.accept()
13     print(addr)
14     while True:
15         try:
16             data = conn.recv(1024)  # 此处异常关闭客户端会出现异常
17         except Exception as e:
18             break  # 跳出里层的循环
19         if not data:
20             break
21         print('-------', str(data, 'utf-8'))
22         obj = subprocess.Popen(str(data, 'utf-8'), shell=True, stdout=subprocess.PIPE)  # PIPE是个类
23         cmd_result = obj.stdout.read()
24         result_len = bytes(str(len(cmd_result)), 'utf-8')  # int和bytes不能直接转,需要有通过str来转
25         conn.sendall(result_len)  # 粘包现象,连续send()
26         conn.recv(1024)
27         conn.sendall(cmd_result)  # 传送的类型是bytes类型
28 
29 sk.close()

cmd_server

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socket
 2 
 3 # 不需要绑定,直接绑定
 4 sk = socket.socket()
 5 address = ('127.0.0.1', 8000)
 6 sk.connect(address)
 7 
 8 while True:
 9     inp = input('>>>')
10     if inp == "exit":
11         break
12     sk.send(bytes(inp, 'utf-8'))  # 不能发空
13     result_len = int(str(sk.recv(1024), 'utf-8'))
14     sk.sendall('ok')  # 解决粘包现象
15     print(result_len)
16     data = bytes()
17     while len(data) != result_len:
18         recv = sk.recv(1024)  # 一次最大接收多少
19         data += recv
20     print(str(data, 'gbk'))  # 如果接受是汉字,需要进行编码
21 
22 sk.close()

cmd_client

6 文件上传

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socket
 2 import subprocess
 3 import os
 4 
 5 sk = socket.socket()
 6 print(sk)
 7 address = ('127.0.0.1', 8000)
 8 sk.bind(address)
 9 sk.listen(3)  # 最大排队数,排队数量为3个。
10 print("waitting...")
11 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
12 
13 while True:
14     conn, addr = sk.accept()
15     while True:
16         data = conn.recv(1024)
17         cmd, filename, filesize = str(data, 'utf-8').split('|')
18         path = os.path.join(BASE_DIR, 'yuan', filename)
19         filesize = int(filesize)
20 
21         f = open(path, 'ab')
22         has_receive = 0
23         while  has_receive != filesize:
24             data = conn.recv(1024)
25             f.write(data)
26             has_receive += len(data)
27         f.close()
28 sk.close()

server

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socket
 2 import os
 3 
 4 sk = socket.socket()
 5 print(sk)
 6 
 7 addresss = ('127.0.0.1', 8000)
 8 sk.connect(addresss)
 9 
10 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
11 
12 inp = input('>>>').strip()  # post|产品目录1.xlsx
13 
14 cmd, path = inp.split('|')
15 path = os.path.join(BASE_DIR, path)  # 文件的绝对路径
16 
17 filename = os.path.basename(path)  # 取名字
18 filesize = os.stat(path).st_size
19 
20 file_info = 'post|%s|%s' % (filename, filesize)
21 sk.sendall(bytes(file_info, 'utf-8'))
22 
23 f = open(path, 'rb')
24 has_sent = 0
25 while has_sent != filesize:
26     data = f.read(1024)
27     sk.sendall(data)
28     has_sent += len(data)  # int数据类型
29 f.close()
30 print('上传成功')
31 
32 sk.close()

client

7 socketserver模块

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socketserver
 2 
 3 
 4 class MyServer(socketserver.BaseRequestHandler):  # 继承里面的类是固定的
 5 
 6     def handle(self):
 7         print('服务端启动...')
 8         while True:
 9             conn = self.request
10             print('来自服务端的地址:', self.client_address)
11             while True:
12                 client_data = conn.recv(1024)
13                 print("收到客户端信息:", str(client_data, 'utf-8'))
14                 # print('服务端准备输入发送数据!')
15                 server_response = input("服务端准输入:")
16                 conn.sendall(bytes(server_response, 'utf-8'))  # 原路返回
17             conn.close()
18 
19 
20 if __name__ == "__main__":
21     server = socketserver.ThreadingTCPServer(('127.0.0.1', 8091), MyServer)
22 
23     server.serve_forever()  # 启动

server

python可以修改地址中的值吗_客户端

python可以修改地址中的值吗_服务端_02

1 import socket
 2 
 3 ip_port = ('127.0.0.1', 8091)
 4 sk = socket.socket()
 5 sk.connect(ip_port)
 6 print('客户端启动:')
 7 
 8 while True:
 9     inp = input("客户端输入:")
10     if inp == 'exit':
11         break
12     sk.sendall(bytes(inp, 'utf-8'))
13     data = sk.recv(1024)
14     print('服务器返回:', str(data, 'utf-8'))
15 
16 sk.close()

client