• socket编程


    socket实现文件上传和下载

    #!/usr/bin/env python
    # coding:utf-8
    import socket
    import struct
    import json
    buffer = 1024
    sk = socket.socket()
    sk.bind(('127.0.0.1',8888))
    sk.listen()
    conn,addr = sk.accept()
    ret = conn.recv(4)
    len_operate_c = struct.unpack('i',ret)[0]
    operate_c = conn.recv(len_operate_c)
    operate_c = operate_c.decode('utf-8')
    if operate_c == 'upload':
        res = conn.recv(4)
        len_head = struct.unpack('i',res)[0]
        head = conn.recv(len_head).decode('utf-8')
        head = json.loads(head)
        filesize = head['filesize']
        filename = head['filename']
        with  open (filename,'wb') as  f:
            while filesize:
                if filesize >= buffer:
                    content = conn.recv(buffer)
                    f.write(content)
                    filesize -= buffer
                else :
                    content = conn.recv(filesize)
                    f.write(content)
                    filesize = 0
    conn.close()
    sk.close()
    server端
    #!/usr/bin/env python
    # coding:utf-8
    def get_filename(file_path):
        return os.path.basename(file_path)
    import socket
    import os
    import json
    import struct
    buffer = 1024
    sk = socket.socket()
    sk.connect(('127.0.0.1',8888))
    operate = ['download','upload']
    for  k,j  in  enumerate(operate,1) :
        print(k,j)
    num = int(input('请输入你的选项: '))
    operate_c = operate[(num-1)]
    len_operate_c = len(operate_c)
    print(len_operate_c)
    res = struct.pack('i',len_operate_c)
    sk.send(res)
    sk.send(operate_c.encode('utf-8'))
    if operate_c == 'upload' :
        head = {'filename':None,'filesize':None,}
        file_path = input("请输入要上传的文件绝对路径 :")
        filename = get_filename(file_path)
        head['filename'] = filename
        filesize = os.path.getsize(file_path)
        head['filesize']=filesize
        json_head = json.dumps(head)
        len_head = len(json_head)
        ret = struct.pack('i',len_head)
        sk.send(ret)
        sk.send(json_head.encode('utf-8'))
        with open (file_path,'rb') as f:
            while filesize:
                if filesize >= buffer :
                    content =  f.read(buffer)
                    sk.send(content)
                    filesize -= buffer
                else :
                    content = f.read(filesize)
                    sk.send(content)
                    filesize = 0
    sk.close()
    client端

     网络编程:实现不同机器上的程序通信

    网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

    基于TCP简单socket通信

    server端

    import  socket
    sk = socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.listen()
    conn,addr = sk.accept()
    ret = conn.recv(1024)
    conn.send(b'hi')
    print(ret)
    conn.close()
    sk.close()
    

     client端

    
    
    import  socket
    sk = socket.socket()
    sk.connect(('127.0.0.1',8080))
    sk.send(b'hello')
    res = sk.recv(1024)
    print(res)
    sk.close()
    
    
    

     服务端长连接

    socket端

    import  socket
    sk = socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.listen()
    # conn,addr = sk.accept()
    while 1:
        conn,addr = sk.accept()
        ret = conn.recv(1024)
        ret = ret.decode('utf-8')
        if ret:
            conn.send(b'hi')
            print(ret)
    server

    client端

    import  socket
    sk = socket.socket()
    sk.connect(('127.0.0.1',8080))
    sk.send(bytes('你好',encoding='utf8'))
    res = sk.recv(1024)
    print(res)
    sk.close()
    client
    sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    sk = socket.socket(family=AF_INET,type=SOCK_STREAM,proto=0,fileno=None)


    参数一:地址簇

        socket.AF_INET IPv4(默认)
        socket.AF_INET6 IPv6

        socket.AF_UNIX 只能够用于单一的Unix系统进程间通信

      参数二:类型

        socket.SOCK_STREAM  流式socket , for TCP (默认)
        socket.SOCK_DGRAM   数据报式socket , for UDP

    基于UDP简单socket通信

    import  socket
    sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    sk.bind(('127.0.0.1',8080))
    msg,(host,port) = sk.recvfrom(1024)
    print(msg)
    sk.sendto(b'hello',(host,port))
    sk.close()
    UDPserver
    import  socket
    sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    ip_port=('127.0.0.1',8080)
    sk.sendto(b'hi',ip_port)
    ret,addr = sk.recvfrom(1024)
    print(ret)
    print(addr)
    sk.close()
    UDPclient

    udp的server不需要监听,也不需要建立连接

    在启动服务之后,只能被动地等待客户端发过来的消息,

    客户端发送消息的同时还会自带地址信息

    消息回复的时候,不仅需要发送消息,还需要把对方地址填上

    使用tcp,出现数据乱,不丢包

    本质问题:不知道客户端发送数据包的大小

    优化算法,连续发送多个send,小的数据包被合并

    使用udp,出现丢包现象,因为udp是尽最大努力交付的协议

     hmac验证客户端的合法性

    import hmac,os
    import  socket
    secret_key=b'egg'
    def conn_auth(conn):
        print('开始验证新链接的合法性')
        msg=os.urandom(32)
        conn.sendall(msg)
        h=hmac.new(secret_key,msg)
        digest=h.digest()
        respone=conn.recv(len(digest))
        return hmac.compare_digest(respone,digest)
    def server_socket():
        sk = socket.socket()
        sk.bind(('127.0.0.1',8080))
        sk.listen()
        while 1:
            conn,addr = sk.accept()
            res = conn_auth(conn)
            print(res)
    
    server_socket()
    server端
    import  socket
    import hmac
    secret_key=b'egg'
    def auth_conn(conn):
        msg=conn.recv(32)
        h=hmac.new(secret_key,msg)
        digest=h.digest()
        conn.sendall(digest)
    
    def client():
        sk = socket.socket()
        sk.connect(('127.0.0.1',8080))
        auth_conn(sk)
        sk.close()
    client()
    client端

    socketserver,在socket的基础上进行封装,可以实时同多个客户端通信

    import socketserver
    class Myserver(socketserver.BaseRequestHandler):
        def handle(self):
            self.data = self.request.recv(1024).strip()
            print("{} wrote:".format(self.client_address[0]))
            print(self.data)
            self.request.sendall(self.data.upper())
    
    if __name__ == "__main__":
        HOST, PORT = "127.0.0.1", 9999
        # 设置allow_reuse_address允许服务器重用地址
        socketserver.TCPServer.allow_reuse_address = True
        # 创建一个server, 将服务地址绑定到127.0.0.1:9999
        server = socketserver.TCPServer((HOST, PORT),Myserver)
        # 让server永远运行下去,除非强制停止程序
        server.serve_forever()
    server端
    import socket
    
    HOST, PORT = "127.0.0.1", 9999
    data = "hello"
    
    # 创建一个socket链接,SOCK_STREAM代表使用TCP协议
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.connect((HOST, PORT))          # 链接到客户端
        sock.sendall(bytes(data + "
    ", "utf-8")) # 向服务端发送数据
        received = str(sock.recv(1024), "utf-8")# 从服务端接收数据
    
    print("Sent:     {}".format(data))
    print("Received: {}".format(received))
    client

    I can feel you forgetting me。。 有一种默契叫做我不理你,你就不理我

  • 相关阅读:
    佛教:禅宗和净土--佛教的归途
    佛教:从精英到世俗
    佛教:神迹的演变。
    收藏品:MP3播放器
    淘书百胜楼
    Spring注解是如何生效的?
    logstash6.8.3 导入 CSV 文件到 ElasticSearch
    三个线程交替按顺序打印ABC之条件队列的理解
    谈谈多线程
    ElasticSearch如何更新集群的状态
  • 原文地址:https://www.cnblogs.com/weidaijie/p/10322260.html
Copyright © 2020-2023  润新知