Python 学习笔记: Socket 初步

 Socket 初步

1 TCP chat server 程序:

import socket
from socket import SOL_SOCKET,SO_REUSEADDR

sk = socket.socket()
# 设置socket的可选项, 允许port重复绑定,防止程序非正常推出时, 再次运行时操作系统尚未解除端口占用。
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

sk.bind(('127.0.0.1', 8090))
sk.listen()
print('TCP chat Server is running...')
conn, addr = sk.accept()
print('%s user is connected...'%addr[0])

while True:
    content = conn.recv(1024).decode('utf-8')
    print(content)
    if content == 'bye':
        conn.send(b'bye')
        break
    info = input('>>>')
    conn.send(bytes(info, encoding='utf-8'))
conn.close()
sk.close()

 

TCP client 程序:

import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8090))
sk.send(bytes('你好!', encoding='utf-8'))
while True:
    ret = sk.recv(1024).decode('utf-8')
    print(ret)
    if ret == 'bye':
        sk.send(b'bye')
        break
    info = input('>>>')
    sk.send(bytes(info,encoding='utf-8'))
sk.close()

 

2 UDP socket , chat server 举例

 

3 TCP 的 文件传输, 使用struct 解决黏包问题

 Server 端:

import socket
import struct
import json
import os

buffer = 512
sk = socket.socket()
ip_port = ('127.0.0.1', 8090)
sk.bind(ip_port)
sk.listen()

conn, addr = sk.accept()

print('%s user is connected...'%addr[0])
pack_head = conn.recv(4)
head_len = struct.unpack('i',pack_head)[0]
json_head = conn.recv(head_len).decode('utf-8')
head = json.loads(json_head)
file = head['filename']
filesize = head['filesize']
copysize = filesize

with open(file,'wb') as f:
    while True:
        if filesize >= buffer:
            cont = conn.recv(buffer)
            f.write(cont)
            filesize -= buffer
        else:
            cont = conn.recv(filesize)
            f.write(cont)
            break

conn.close()
print('filesize is %d'%head['filesize'])
print('file get size %d'%os.path.getsize(file))
print('copysize is %d'%copysize)
if head['filesize'] == os.path.getsize(file):
    print('接收文件 %s 成功。。。'%file)
else:
    print('接收文件 %s 失败。。。'%file)

Client 端:

import socket
import os
import struct
import json

buffer = 512
sk = socket.socket()
ip_port = ('127.0.0.1', 8090)
sk.connect(ip_port)

filepath = r'C:\Users\cuiyu\Documents\pythonclass\01 Python全栈9期(第一部分):基础+模块+面向对象+网络编程\day01'
filename = r'01 python fullstack s9day1 自我介绍今日内容大纲.mp4'
file = os.path.join(filepath,filename)
filesize = os.path.getsize(file)

head = {'filepath': filepath,'filename': filename,'filesize':filesize}

json_head = json.dumps(head)
byte_head = bytes(json_head, encoding='utf-8')
head_len = len(byte_head)
pack_len = struct.pack('i', head_len)

sk.send(pack_len)
sk.send(byte_head)

with open(file,'rb') as f:
    while True:
        if filesize >= buffer:
            cont = f.read(buffer)
            sk.send(cont)
            filesize -= buffer
        else:
            cont = f.read(filesize)
            sk.send(cont)
            break
print('传送完毕。。。')
sk.close()

注意: buffer = 1024 以上的数据时会出现传输的接收问题, 猜测可能与写盘的速度有关。适当降低buffer 的大小可以解决此问题。

 

4 hmac 验证socket客户端的合法性

 

Server 端:

import os
import socket
import hmac

sk = socket.socket()
sk.bind(('127.0.0.1', 8090))
sk.listen()

secret_key = b'egg'

conn, addr = sk.accept()

def check_login(conn):
    msg = os.urandom(32)
    h = hmac.new(secret_key, msg)
    h_digest = h.digest()
    conn.send(msg)
    client_digest = conn.recv(1024)
    return hmac.compare_digest(h_digest, client_digest)


ret = check_login(conn)
if ret:
    print('合法的客户端')
else:
    print('非法的客户端')

conn.close()

 

Client 端:

import socket
import hmac

secret_ket = b'egg'
sk = socket.socket()
sk.connect(('127.0.0.1',8090))

msg = sk.recv(1024)
h = hmac.new(secret_ket,msg)
client_digest = h.digest()
sk.send(client_digest)
print('已发送hmac认证')
sk.close()

 

5 socketserver 模块

import socketserver


class MySocketServer(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.request.recv(1024).decode('utf-8'))  # self.request 就是 conn


if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1', 8090),MySocketServer)
    server.serve_forever()

 

posted @ 2018-11-22 17:10  程序猿🌽  阅读(157)  评论(0编辑  收藏  举报