zoukankan      html  css  js  c++  java
  • python学习记录-socket模块

      主要使用的模块是socket模块,在这个模块中可以找到socket()函数,该函数用于创建套接字对象。套接字也有自己的方法集,这些方法可以实现基于套接字的网络通信。

    1、socket类型

    构造函数:

    socket.socket(family=AF_INETtype=SOCK_STREAMproto=0fileno=None)

    family: 套接字地址家族,Python支持 AF_INET (默认),AF_INET6AF_UNIXAF_CAN 和 AF_RDS

    type:套接字类型,SOCK_STREAM (默认), SOCK_DGRAMSOCK_RAW

    proto:协议编号(默认为0)

    2、socket常量

    socket常量 描述
    socket.AF_UNIX 只能够用于单一的Unix系统进程间通信
    socket.AF_INET 服务器之间网络通信,IPv4
    socket.AF_INET6 IPv6
    socket.SOCK_STREAM 流套接字,实现TCP协议
    socket.SOCK_DGRAM 数据包类型套接字,实现UDP协议
    socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。

     

     

     

     

     

    3、socket函数

    socket函数 描述
    服务器端函数
    socket.bind(address) 将套接字绑定到网络地址,address格式为(host, port)
    socket.listen([backlog]) 开始监听TCP传入连接。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。
    socket.accept() 接受TCP连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。
    客户端函数
    socket.connect(address) 连接到address处的套接字。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
    socket.connect_ex(adddress) 功能与connect(address)相同,但是成功返回0,失败返回errno的值。
    socket公用函数
    socket.resv(buffsize[,flags]) 接受套接字的数据。数据以bytes形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
    socket.resvfrom(buffsize[,flags]) 接受套接字的数据。与recv()类似,但返回值是(data,address)。其中data是bytes对象,包含接受的数据,address是发送数据的套接字地址。多用于UDP
    socket.send(bytes[,flags]) 发送数据到套接字,该套接字必须为已连接的远程套接字(TCP)。可返回发送数据的字节数。应用程序负责检查所有的数据是否已经发送;如果只传输一些数据,应用程序需要尝试交付剩余的数据
    socket.sendall(bytes[,flags]) 类似send()函数,但该函数会一直发送数据知道发送完毕或发生错误
    socket.sendto(bytes, addtess) 发送数据到套接字,该套接字不应已连接到远程套接字(UDP),目标套接字由address提供
    socket.close() 关闭套接字
    socket.getpeername() 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)
    socket.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,port)
    socket.setsockopt(level,optname,value) 设置给定套接字选项的值
    socket.getsockopt(level,optname[.buflen]) 返回套接字选项的值
    socket.settimeout(timeout) 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
    socket.gettimeout() 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None
    socket.fileno() 套接字的文件描述符
    socket.setblocking(flag) 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
    socket.makefile() 创建一个与该套接字相关连的文件

    4、socket编程模型

    代码实例:

    TCP服务器及客户端代码

     1 #!/usr/bin/python
     2 # -*- coding:utf-8 -*-
     3 import socket
     4 import threading
     5 from time import asctime
     6 from multiprocessing import Lock
     7 
     8 
     9 lock = Lock()
    10 
    11 
    12 def tcplink(sock, addr):
    13     print('. . . connecting from %s:%s ' % addr)
    14     sock.send(b'Welcome !')
    15     while True:
    16         # 接收数据
    17         data = sock.recv(1024)
    18         if not data or data.decode('utf-8') == 'exit':
    19             break
    20         # 通过在客户端中输入口令和密码来关闭服务器
    21         elif data.decode('utf-8') == 'close the server!':
    22             global server
    23 
    24             passwd = sock.recv(1024)
    25             if passwd.decode('utf-8') == '1111':
    26                 with lock:
    27                     server.close()
    28 
    29             return  # 跳出函数tcplink,则子进程也执行完毕
    30         else:
    31             # 发送数据
    32             sock.send(('%s  %s' % (asctime(), data.decode())).encode())
    33     # 客户端已关闭,关闭该临时套接字
    34     sock.close()
    35     print('Connection from %s:%s close . . .' % addr)
    36 
    37 
    38 ip_port = ('127.0.0.1', 5110)
    39 # 创建基于IPv4和TCP协议的socket
    40 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    41 # 绑定端口
    42 server.bind(ip_port)
    43 # 监听端口
    44 server.listen(5)
    45 print('Server is open
    *********************************')
    46 
    47 while True:
    48     try:
    49         print('Waiting for new connection . . . ')
    50         # 接受一个新链接
    51         # sock为临时套接字,用于客户端与服务器的数据交互
    52         sock, addr = server.accept()  # 当服务器被子进程中关闭会有OSError
    53         # 创建新线程来处理TCP连接
    54         t = threading.Thread(target=tcplink, args=(sock, addr))
    55         t.start()
    56     except OSError:
    57         print('*********************************
    Server is closed')
    58         exit()
    TCP服务器
     1 #!/usr/bin/python
     2 # -*- coding:utf-8 -*-
     3 import socket
     4 
     5 
     6 ip_port = ('127.0.0.1', 5110)
     7 # 创建基于IPv4和TCP协议的socket
     8 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     9 # 建立连接
    10 client.connect(ip_port)
    11 print(client.recv(1024).decode())
    12 
    13 while True:
    14     data = input('Please enter data: ')
    15     # 发送数据
    16     client.send(data.encode())
    17     if not data or data == 'exit':
    18         break
    19     # 监听到输入为关闭服务器的特殊口令时:
    20     elif data == 'close the server!':
    21         passwd = input('Password: ')
    22         client.send(passwd.encode())
    23     print(client.recv(1024).decode())
    24 client.close()
    TCP客户端

    UDP服务器及客户端代码

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    import socket
    from time import asctime
    
    
    ip_port = ('127.0.0.1', 5002)
    server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server.bind(ip_port)
    print('Server is opening . . . ')
    
    while True:
        print(' . . . Waiting for new connection')
        data, addr = server.recvfrom(1024)
        if data == b'close the server!':
            print('get close')
            passwd = server.recv(1024)
            if passwd == b'1111':
                server.sendto(b'Server is closed !', addr)
                break
        elif not data or data == b'exit':
            pass
        else:
            print('Received from %s:%s . . . ' % addr)
            server.sendto(b'%s <--> %s' % (asctime().encode(), data), addr)
    server.close()
    UDP服务器
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    import socket
    
    
    ip_port = ('127.0.0.1', 5002)
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    while True:
        data = input('Please input: ')
        if not data or data == 'exit':
            break
        elif data == 'close the server!':
            client.sendto(data.encode(), ip_port)
            passwd = input('Password: ')
            client.sendto(passwd.encode(), ip_port)
        else:
            client.sendto(data.encode(), ip_port)
            response = client.recv(1024).decode()
            print(response)
    
    client.close()
    UDP客户端

    参考和引用:

    http://yangrong.blog.51cto.com/6945369/1339593/

    http://www.cnblogs.com/aylin/p/5572104.html

    https://docs.python.org/3/library/socket.html

  • 相关阅读:
    解决加密PDF文档无法复制文字的问题
    Linux创建用户时让每个用户家目录中自带说明文档
    Linux基础命令cp之拷贝隐藏文件
    Linux基础命令之getent
    Linux用户和组管理命令-用户创建useradd
    Linux用户和组管理命令-用户删除userdel
    Linux用户和组管理命令-用户属性修改usermod
    Linux用户和组管理命令-切换用户su
    Linux-京西百花山
    tee命令
  • 原文地址:https://www.cnblogs.com/thunderLL/p/6435762.html
Copyright © 2011-2022 走看看