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_UNIXunix不同进程间通信

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.recv1024) 进行阻塞,将两个连续的conn.send()分隔开

 

编码拾遗:

  • strunicode
  • 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()
View Code

    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()
View Code

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()
View Code

    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()
View Code

 

 

server 下的方法:

bind()

listen()

accept()

 

recv()

send( string )

sendall()

 

close()

 

 

client 下的方法:

connect()

 

recv()

send( string )

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

 

close()

猪猪侠要努力呀!
原文地址:https://www.cnblogs.com/mlllily/p/10336535.html