1. 程式人生 > >25 python 初學(socket,socketserver)

25 python 初學(socket,socketserver)

socket 重寫 原則 端口 gbk 傳輸 類型 十六進制 com

參考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)