代码改变世界

2018.3.31学习笔记(socket基本操作,I/O多路复用有补充)

2018-03-31 22:12  冒牌权限  阅读(72)  评论(0)    收藏  举报

简单交互

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#####服务端#####
import socket

sk = socket.socket()
sk.bind(('127.0.0.1',10000))#设置监听ip和端口
sk.listen(5)#监听,值代表可等待数

conn,address = sk.accept()#等待客户端连接,把连接赋值给conn,客户端ip和端口赋值给address
conn.sendall(bytes('老铁,你来啦',encoding='utf-8'))#python3里面只能传字节

#####客户端#####
import socket

obj = socket.socket()
obj.connect(('localhost',10000))#要请求的服务器ip和端口
ret = obj.recv(1024)#最多接受1024字节
print(str(ret,encoding="utf-8"))
obj.close()#连完后关闭连接

简单文件上传

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#####服务端#####
import socket

sk = socket.socket()
sk.bind(('127.0.0.1',10000))#设置监听ip和端口
sk.listen(5)#监听,值代表可等待数

while True:
    conn,address = sk.accept()#等待客户端连接,把连接赋值给conn,客户端ip和端口赋值给address
    conn.sendall(bytes('老铁,你来啦',encoding='utf-8'))#python3里面只能传字节

    file_size = str(conn.recv(1024),encoding='utf8')#传输的都是字节,转成字符
    conn.sendall(bytes('ack',encoding='utf-8'))#返回一个ACK,表示收到了文件大小,解决缓冲区导致的粘包问题
    total_size = int(file_size)#文件传输都是以字符形式,所以这里要转成数字
    #print(total_size)调试用
    b_size = 0
    with open('new.txt', 'wb') as new_file:
        while True:
            if b_size == total_size:#传输完成,文件小等于一开始收到的大小,跳出循环
                break
            new_line = conn.recv(1024)
            new_file.write(new_line)
            b_size += len(new_line)


#####客户端#####
import socket,os

obj = socket.socket()
obj.connect(('localhost',10000))#要请求的服务器ip和端口
ret = obj.recv(1024)#最多接受1024字节
print(str(ret,encoding="utf-8"))

size = os.stat('db.txt').st_size#获取文件大小
obj.sendall(bytes(str(size),encoding='utf-8'))#把文件大小传给服务端
obj.recv(1024)#确认接收方收到发过去的大小,解决由于缓冲区导致的粘包问题
with open('db.txt','rb') as f:
    for line in f:
        obj.sendall(line)

obj.close()#连完后关闭连接

并发处理多个客户端之socketserver

  1.创建类,必须继承socketserver.BaseRequestHandler

  2.必须有handle方法

  3.对象执行serve_forever循环起来

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#####服务端#####
import socketserver

class Myserver(socketserver.BaseRequestHandler):#这个类必须继承socketserver的这个类
    def handle(self):#这个方法必须写成handle()
        # self.request#连接
        # self.client_address#客户端ip
        # self.server#服务器ip
        conn = self.request
        conn.sendall(bytes('老铁,你来啦', encoding='utf-8'))  # python3里面只能传字节

if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1',10000),Myserver)
    server.serve_forever()#其实就类似于我们之前写的循环,只是人家写的比较流弊,执行Myserver类里边的handle()方法