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_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()

以上是关于25 python 初学(socket,socketserver)的主要内容,如果未能解决你的问题,请参考以下文章

Python学习笔记(socket)

python socket timeout设置

Python--网络编程-----socket代码实例

python Socket实例练习

python之路-socke开发

python