socket通訊

蘇格尼塞發表於2020-10-17

server端

import os
from socket import socket
import hashlib


def chat(connect: socket, address):
    while True:
        message = input('>>>')
        # 9、傳送訊息使用send,傳送的內容需要使用encode函式將字串轉換成bytes型資料
        connect.send(message.encode())
        if message in ['拜拜', '再見', 'Bye-Bye']:
            return
        # 10、接受資料
        re_message = connect.recv(1024).decode(encoding='utf-8')
        # address是一個列表,第一個元素是訊息源ip地址,第二個是埠號
        print(f'{address[0]}:{re_message}')
        if re_message in ['拜拜', '再見', 'Bye-Bye']:
            return


def send_image(connect: socket):
    # 獲取資料夾中所有圖片的名稱(列表形式存貯)
    all_image_name = os.listdir('./serverImage')

    message = ''
    for index, item in enumerate(all_image_name):
        message += f'{index}.{item}  '
    # 傳送圖片資訊
    connect.send(message.encode())
    # 接受客戶端的選擇
    index = connect.recv(1024).decode(encoding='utf-8')
    try:
        if 0 <= int(index) < len(all_image_name):
            image_name = all_image_name[int(index)]
            print('傳送圖片...')
            with open('serverImage/'+image_name, 'rb') as f:
                image_content = f.read()
                # 生成圖片的摘要
                hash = hashlib.md5()
                hash.update(image_content)
                digest = hash.hexdigest()
                # 傳送摘要
                connect.send(digest.encode())
                # 傳送圖片
                connect.send(image_content)
        else:
            print('取消圖片傳送')
    except ValueError:
        print('取消圖片傳送')




def create_server():
    # 1、建立套接字物件
    server = socket()
    # 2、服務端繫結Ip地址和埠號
    server.bind(('10.7.165.86', 4568))
    # 3、監聽請求,其中的200為最大通訊的數量
    server.listen(200)
    # 4、等待客戶端的連線
    while True:
        print('等待.....')
        # 5、接受客戶端的請求-這句話會阻塞執行緒,直到有客戶端的請求才會執行
        connect, address = server.accept()
        # 建立連線後的操作
        while True:
            # 6、接受訊息,接收到的訊息都是二進位制(bytes),需要使用decode轉換成字串型別資料
            message = connect.recv(1024).decode(encoding='utf-8')
            # 7、功能選擇
            if message == 'chat':
                print('聊天')
                chat(connect, address)
            elif message == 'image':
                print('發圖片')
                send_image(connect)
            elif message == 'close':
                # 8、斷開伺服器的連線
                connect.close()
                break


if __name__ == '__main__':
    create_server()
    # int('hj')

client端

import re
from socket import socket
import hashlib
import uuid



def get_digest(data):
    hash = hashlib.md5()
    hash.update(data)
    return hash.hexdigest()


def chat(client):
    # 告訴伺服器現在要聊天
    client.send('chat'.encode(encoding='utf-8'))
    while True:
        re_message = client.recv(1024).decode(encoding='utf-8')
        print('伺服器:'+re_message)
        if re_message in ['拜拜', '再見', 'Bye-Bye']:
            return

        message = input('客戶端:')
        client.send(message.encode())
        if message in ['拜拜', '再見', 'Bye-Bye']:
            return


def get_image(client):
    # 告訴伺服器現在要拿圖
    client.send('image'.encode(encoding='utf-8'))

    # 接受圖片資訊
    image_message = client.recv(1024).decode(encoding='utf-8')
    print(image_message+'')
    index = input('請選擇(輸入標號,如果不需要輸入其他值):')
    # 傳送選擇的圖片的標號
    client.send(index.encode())
    # 根據選擇判斷是否需要接受圖片
    all_index = re.findall(r'\b(\d+)\.', image_message)
    if index in all_index:
        print('接受圖片')
        # 接受圖片摘要
        digest = client.recv(1024).decode(encoding='utf-8')
        # 接受圖片
        image_data = bytes()
        while True:
            image_data += client.recv(2048)
            if get_digest(image_data) == digest:
                print('圖片接受完成')
                with open('clientImage/'+uuid.uuid4().hex, 'wb') as f:
                    f.write(image_data)

                break
    else:
        print('不接受圖片')


def close_connection(client):
    # 告訴伺服器關閉連線
    client.send('close'.encode(encoding='utf-8'))
    client.close()
    exit()


def create_client():
    client = socket()
    client.connect(('10.7.165.86', 4568))

    while True:
        print('1. 聊天\n2. 獲取圖片\n3. 斷開連線')
        value = input('請選擇(1~3):')
        if value == '1':
            # print('聊天')
            chat(client)
        elif value == '2':
            # print('獲取圖片')
            get_image(client)

        elif value == '3':
            print('斷開連線')
            close_connection(client)
        else:
            print('輸入有誤!')


if __name__ == '__main__':
    create_client()
    # message = '0.avatar.png  1.icon2.png  2.tie2.png  3.luffy1.png '
    # print(re.findall(r'\b(\d+)\.', message))
    # print(uuid.uuid4().hex)

相關文章