25 python 初学(socket,socketserver)
Posted mlllily
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了25 python 初学(socket,socketserver)相关的知识,希望对你有一定的参考价值。
参考blog :www.cnblogs.com/yuanchenqi/articles/5692716.html
1. sk = socket.socket()
里面有两个重要的参数,family 和 type
type:
SOCK_STREAM : tcp 默认
SOCK_DGRAM :udp
family:
family = AF_INET : 服务器之间的通信(默认)
family = AF_INET6 : 服务器之间的通信
family=AF_UNIX:unix不同进程间通信
server 下的方法:
bind() 、 listen() 、 accept()
recv() 、 send() 、 sendall()
close()
client 下的方法:
connect()
recv() 、send( string ) 、sendall() # 传送的类型一定是 byte 类型
close()
# _author: lily # _date: 2019/1/25 # server 端 import socket sk = socket.socket() address = (\'127.0.0.1\', 8000) sk.bind(address) sk.listen(3) print(\'waiting\') # print(sk) conn, address_client = sk.accept() while 1: send_data = input(\'input>>\') if send_data == \'exit\': break conn.send(bytes(send_data, \'utf8\')) rec_data = conn.recv(1024) print(str(rec_data, \'utf8\')) conn.close()
# _author: lily # _date: 2019/1/25 # client 端 import socket sk = socket.socket() # print(sk) adress = (\'127.0.0.1\', 8000) sk.connect(adress) while 1: rec_data = sk.recv(1024) # 会阻塞,直到收到数据 if not rec_data: break print(str(rec_data, \'utf8\')) send_data = input(\'>>\') sk.send(bytes(send_data, \'utf8\')) sk.close()
socket 流程:
1. 先开启服务端,bind 绑定ip 和端口;
2. 其次 listen 监听,里面的数字表示有多少客户端可排队(不包括当前正在通信的,排队表示可连接但是不能通信。比如设定上限为3,当第四个客户端来连接时就会报错无法连接)
3. 接着需要 accept(),阻塞等待连接。accept 接受到的值是对方的 sk,进行连接(相当于两端建立了一个通道,server 和 client 都使用的这个通道,只是各自的命名不同)。
4. 保证一收一发原则
5. 关闭时关闭这个通道。 conn.close()
1. 客户端进行连接,先创建一个socket 对象 sk
2. sk 使用 connect 连接服务端
3. 保证一收一发原则
4. 关闭时 sk.close()
粘包现象的解决办法:
加一个 conn.recv(1024) 进行阻塞,将两个连续的conn.send()分隔开
编码拾遗:
- str:unicode
- bytes:十六进制
- 由 str -> bytes:编码
s = ‘hello 你好’
b = bytes(s, ‘utf8’)
b2 = s.encode(‘utf8’) # 两个是一样的
- 由 bytes -> str:解码
s2 = str(b2, ‘utf8’)
s2 = b2.decode(‘utf8’)
socketserver:
1. 调用模块
2. 自己写一个类,继承 socketserver.BaseRequestHandler,并重写 handle()方法
3. main 方法内:
调用 socketserver.ThreadingTCPServer,创建一个实例
# _author: lily # _date: 2019/1/28 # Server 端 import socketserver class myserver(socketserver.BaseRequestHandler): # 主要逻辑 def handle(self): print(\'server starting...\') while True: conn = self.request print(self.client_address) while True: client_data = conn.recv(1024) print(str(client_data, \'utf8\')) print(\'waiting\') send_data = input(\'input>>\') conn.sendall(bytes(send_data, \'utf8\')) # conn.sendall(client_data) conn.close() if __name__ == \'__main__\': server = socketserver.ThreadingTCPServer((\'127.0.0.1\', 8091), myserver) server.serve_forever()
# _author: lily # _date: 2019/1/28 # client 端 import socket address = (\'127.0.0.1\', 8091) sk = socket.socket() sk.connect(address) print(\'client starting...\') while True: data = input(\'input>>\') sk.sendall(bytes(data, \'utf8\')) recv_data = sk.recv(1024) print(str(recv_data, \'utf8\')) sk.close()
实例:
cmd 命令:
server 端:

# _author: lily # _date: 2019/1/26 import socket import subprocess sk = socket.socket() address = (\'127.0.0.1\', 8000) sk.bind(address) sk.listen(3) print(\'waiting\') # print(sk) conn, address_client = sk.accept() while 1: try: rec_data = conn.recv(1024) except Exception: break if not rec_data: break print(\'--client message--\', str(rec_data, \'utf8\')) a = subprocess.Popen(str(rec_data, \'utf8\'), shell=True, stdout=subprocess.PIPE) cmd_result = a.stdout.read() result_len = bytes(str(len(cmd_result)), \'utf8\') conn.sendall(result_len) conn.recv(1024) conn.sendall(cmd_result) # send_data = input(\'input>>\') # conn.send(bytes(send_data, \'utf8\')) conn.close()
client 端:

# _author: lily # _date: 2019/1/26 import socket sk = socket.socket() # print(sk) adress = (\'127.0.0.1\', 8000) sk.connect(adress) while 1: send_data = input(\'>>\') if send_data == \'exit\': break sk.send(bytes(send_data, \'utf8\')) result_len = int(str(sk.recv(1024), \'utf8\')) print(result_len) rec_data = bytes() sk.sendall(bytes(\'ok\', \'utf8\')) while len(rec_data) != result_len: rec_data += sk.recv(1024) # 会阻塞,直到收到数据 print(str(rec_data, \'gbk\')) sk.close()
ftp 传输:
server 端:

# _author: lily # _date: 2019/1/27 import socket import subprocess import os sk = socket.socket() address = (\'127.0.0.1\', 8000) sk.bind(address) sk.listen(3) print(\'waiting\') BASE_DIR = os.path.dirname(os.path.abspath(__file__)) while 1: conn, address_client = sk.accept() while 1: data = conn.recv(1024) cmd, filename, filesize = str(data, \'utf8\').split(\'|\') path = os.path.join(BASE_DIR, \'picture\', filename) filesize = int(filesize) f = open(path, \'ab\') has_receive = 0 while has_receive != filesize: data = conn.recv(1024) f.write(data) has_receive += len(data) f.close() conn.close()
client 端:

# _author: lily # _date: 2019/1/27 import socket import os sk = socket.socket() BASE_DIR = os.path.dirname(os.path.abspath(__file__)) adress = (\'127.0.0.1\', 8000) sk.connect(adress) while 1: send_data = input(\'>>\').strip() # post|11.png cmd, path = send_data.split(\'|\') path = os.path.join(BASE_DIR, path) filename = os.path.basename(path) file_size = os.stat(path).st_size file_info = \'post|%s|%s\' % (filename, file_size) sk.sendall(bytes(file_info, \'utf8\')) f = open(filename, \'rb\') has_sent = 0 while has_sent != file_size: data = f.read(1024) sk.sendall(data) has_sent += len(data) f.close() print(\'success\') sk.close()
server 下的方法:
bind()
listen()
accept()
recv()
send( string )
sendall()
close()
client 下的方法:
connect()
recv()
send( string )
sendall() # 传送的类型一定是 byte 类型
close()
以上是关于25 python 初学(socket,socketserver)的主要内容,如果未能解决你的问题,请参考以下文章