25 python 初学(socket,socketserver),,参考blog :ww


参考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 socketsk = 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 socketsk = 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:unicodebytes:十六进制由 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 socketserverclass 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 socketaddress = (‘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/26import socketimport subprocesssk = 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()
View Code

client 端:

技术分享图片
# _author: lily# _date: 2019/1/26import socketsk = 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()
View Code

ftp 传输:

server 端:

技术分享图片
# _author: lily# _date: 2019/1/27import socketimport subprocessimport ossk = 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()
View Code

client 端:

技术分享图片
# _author: lily# _date: 2019/1/27import socketimport ossk = 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()
View Code

server 下的方法:

bind()

listen()

accept()

recv()

send( string )

sendall()

close()

client 下的方法:

connect()

recv()

send( string )

sendall() # 传送的类型一定是 byte 类型

close()

25 python 初学(socket,socketserver)

评论关闭