• Python系列8之socket


    目录

      socket  

      简单的聊天机器人

      简单的ftp上传

      粘包问题的解决

    一. socket模块

      socket,俗称套接字,其实就是一个ip地址和端口的组合。类似于这样的形式(ip,  port),其中ip代表的是某个主机,port代表的是某个应用,我们可以通过socket和另外的一台主机进行通信。

      关于socket源码的解析在tarnado系列文章中,正在写中。。。。。

      1. 通信的方式

        tcp通信

        udp通信

        基于unix的通信

       2. socket的方法 

    # 暂时知道的也就这么多,之后要是在用到其他的我会继续进行保存
        Methods of socket objects (keyword arguments not allowed):
        
        _accept() -- accept connection, returning new socket fd and client address
        bind(addr) -- bind the socket to a local address 给本地地址绑定一个socket套接字
        close() -- close the socket 关闭一个套接字
        connect(addr) -- connect the socket to a remote address     连接到远端主机
        connect_ex(addr) -- connect, return an error code instead of an exception
        dup() -- return a new socket fd duplicated from fileno()
        fileno() -- return underlying file descriptor
        getpeername() -- return remote address [*]
        getsockname() -- return local address
        getsockopt(level, optname[, buflen]) -- get socket options
        gettimeout() -- return timeout or None
        listen([n]) -- start listening for incoming connections
        recv(buflen[, flags]) -- receive data   接受数据
        recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)    接受数据到缓冲区中,
        recvfrom(buflen[, flags]) -- receive data and sender's address
        recvfrom_into(buffer[, nbytes, [, flags])
          -- receive data and sender's address (into a buffer)
        sendall(data[, flags]) -- send all data 发送数据给远端主机,3.x之后只能发送字节形式,因此在发送的时候一般要进行转换bytes
        send(data[, flags]) -- send data, may not send all of it 也是发送数据,区别在于send发送的不完整,随机进行发送的,二sendall发送的完整
        sendto(data[, flags], addr) -- send data to a given address 基于udp发送数据的
        setblocking(0 | 1) -- set or clear the blocking I/O flag    是否设置成阻塞模式0 代表阻塞,1代表非阻塞
        setsockopt(level, optname, value) -- set socket options     设置一些socket的桉树
        settimeout(None | float) -- set or clear the timeout    设置超时市场
        shutdown(how) -- shut down traffic in one or both directions    
        if_nameindex() -- return all network interface indices and names
        if_nametoindex(name) -- return the corresponding interface index
        if_indextoname(index) -- return the corresponding interface name
     
         [*] not available on all platforms!

    二. 简单的聊天机器人

      如果发送一个数据,服务器就会给他回复一个数据 + 你好

     1 # -*- coding:utf-8 -*-
     2 # zhou
     3 # 2017/7/3
     4 
     5 import socket
     6 # 创建一个server对象
     7 server_obj = socket.socket()
     8 # 绑定一下端口
     9 server_obj.bind(("127.0.0.1", 8888, ))
    10 # 设置监听的等待队列长度为5,当大于5的时候就拒绝连接
    11 server_obj.listen(5)
    12 
    13 while True:
    14     # 等待接受客户端的连接,为阻塞方式
    15     conn, address = server_obj.accept()
    16     # 发送欢迎信息
    17     conn.sendall(bytes("欢迎来到简单的聊天室..", encoding='utf-8'))
    18     while True:
    19         # 接受到对面的消息就会把对面消息后面加上你好重新发送回去
    20         ret = str(conn.recv(1024), encoding='utf-8')
    21         if ret == 'q':
    22             # 如果对面发送的为q就退出
    23             break
    24         conn.sendall(bytes(ret + ",你好", encoding='utf-8'))
    server
    # -*- coding:utf-8 -*-
    # zhou
    # 2017/7/3
    
    import socket
    
    client = socket.socket()
    client.connect(("127.0.0.1", 8888, ))
    # 接受欢迎信息并打印
    ret = str(client.recv(1024), encoding='utf-8')
    print(ret)
    
    while True:
        message = input("请输入您要发送的内容:")
        client.sendall(bytes(message, encoding='utf-8'))
        if message == 'q':
            break
        ret = str(client.recv(1024), encoding='utf-8')
        print(ret)
    client

    三. 简单的ftp上传

      实现了将一个图片上传到服务器端

     1 # -*- coding:utf-8 -*-
     2 # zhou
     3 # 2017/7/2
     4 
     5 import socket
     6 
     7 server = socket.socket()
     8 server.bind(("127.0.0.1", 9998, ))  # 绑定ip
     9 server.listen(5)
    10 
    11 while True:
    12     conn, address = server.accept()
    13     # 连接之后首先接收文件大小
    14     file_size = int(str(conn.recv(1024), encoding='utf-8'))
    15     # 用来解决粘包问题的
    16     conn.sendall(bytes("1001", encoding='utf-8'))
    17     # 已经接受的文件大小
    18     has_size = 0
    19     num = 1
    20     # 连接之后接收文件
    21     f = open("new.jpg", 'wb')
    22     while True:
    23         num += 1
    24         if file_size == has_size:
    25             break
    26         data = conn.recv(1024)
    27         f.write(data)
    28         has_size += len(data)
    29     f.close()   # 关闭文件
    ftpserver
     1 # -*- coding:utf-8 -*-
     2 # zhou
     3 # 2017/7/2
     4 
     5 
     6 import os
     7 import socket
     8 
     9 client = socket.socket()
    10 
    11 client.connect(("127.0.0.1", 9998), )
    12 # 传送文件大小
    13 file_size = os.stat("1.jpg").st_size
    14 print(file_size)
    15 # 发送文件大小
    16 client.sendall(bytes(str(file_size), encoding='utf-8'))
    17 client.recv(1024)   # 解决粘包问题
    18 # 发送文件
    19 with open("1.jpg", 'rb') as f:
    20     for line in f:
    21         client.sendall(line)
    22 client.close()
    ftpclient

    四. 粘包问题的解决

      对于上面第三个ftp上传进行的描述,

      解决粘包的问题,当我们上传一个文件的时候,首先上传他的大小,当我们上传完大小之后要在写一句接受的语句,而服务器端在接受到文件大小之后要给我们立马发送一个数据用来确认,这样我们就可以完美的将数据喝大小分割开了。

      

  • 相关阅读:
    PyQt5基础应用一
    常用SQL
    常用vim命令
    原生Ajax XMLHttpRequest对象
    跨域两种解决方案CORS以及JSONP
    Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析
    Django缓存机制--rest_framework中节流源码使用的就是django提供的缓存api
    Django2.0 models中的on_delete参数
    【开发工具IDE】Eclipse 安装 Maven 的 m2eclipse 插件
    【Java】CSVUtils
  • 原文地址:https://www.cnblogs.com/huwentao/p/7113483.html
Copyright © 2020-2023  润新知