zoukankan      html  css  js  c++  java
  • python网络编程基础

      Socket(套接字)始于Unix,即人们所说的BSD Unix。socket家族有两种:基于文件系统的和基于网络的。第一种是基于文件系统的,地址家族表示为:AF_UNIX(或AF_LOCAL);第二种是网络Socket,是基于网络的,地址家族表示为AF_INET(AF_INET6表示ipv6)。

      在Python 2.5 中加入了一种 Linux 套接字的支持:AF_NETLINK(无连接[见下])套接字家族让用户代码与内核代码之间的 IPC 可以使用标准 BSD 套接字接口。Python 只支持 AF_UNIX,AF_NETLINK,和 AF_INET 家族。这里将介绍使用最广泛的一个:AF_INET。

      根据套接字类型,可以分为面向连接的和无连接的。

      面向连接的,在通讯之前需建立一条连接,这种通讯方式提供了顺序的,可靠的,不会重复的数据传输,而且也不会被加上数据边界。实现这种连接的主要协议就是传输控制协议(即 TCP),其对应的套接字类型为 SOCK_STREAM。套接字使用 Internet 协议(IP)来查找网络中的主机,即TCP/IP协议来支持面向连接套接字。

      无连接的,无需建立连接就可以进行通讯。实现这种连接的主要协议就是用户数据报协议(即 UDP) ,指定套接字类型为 SOCK_DGRAM。套接字使用 Internet 协议来查找网络中的主机,即UDP/IP协议来支持无连接套接字。

      1. socket()模块函数

      创建socket()套接字的语法如下:

      socket(socket_family, socket_type, protocol=0)

      socket_family一般为AF_UNIX或者AF_INET,socket_type可以是SOCK_STREAM或者SOCK_DGRAM,protocol一般不填,默认为0。

      由于socket模块中有太多的属性,这里使用"from socket import *"以减少代码长度。

      创建一个TCP/IP的套接字:

      tcpsocket = socket(AF_INET, SOCK_STREAM)

      同样的,创建一个UDP/IP的套接字:

      udpsocket = socket(AF_INET, SOCK_STREAM)

      

      2. 套接字对象(内建)方法

      python中常用的套接字对象函数如下:

      3. 基于TCP的C/S模型

      3.1 创建TCP服务端

      TCP服务端的一般设计流程如下:

    ss = socket()             # 创建服务器套接字
    ss.bind()                 # 绑定地址到套接字
    ss.listen()               # 监听连接
    inf_loop():               # 服务器端无限循环
      cs = ss.accept()      # 接受客户端连接
    comm_loop:                # 通信循环
      cs.recv() / cs.send() # 传输数据(发送/接受)
    cs.close()                # 关闭客户端套接字
    ss.close()                # 关闭服务器端套接字(可选)

      3.2 创建TCP客户端

      TCP客户端的一般设计流程如下:

    cs = socket()             # 创建客户端套接字
    cs.connect()              # 尝试连接服务器
    comm_loop:                # 通信循环
      cs.send() / cs.recv()  # 传输数据(发送/接受)
    cs.close()                # 关闭客户端套接字

      3.3 TCP的C/S套接字模型

      下面是一个完整的C/S套接字模型。服务端采用多线程来处理客户端的请求,并且使用setsockopt()函数达到端口复用。

    ## tcp_server.py
    #!/usr/bin/env python
    # coding=utf-8
    
    import socket
    import threading
    
    bind_ip = '0.0.0.0'
    bind_port = 6666
    
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
    server.bind((bind_ip, bind_port))
    server.listen(5)
    print '[*] Listening on %s:%d' % (bind_ip, bind_port)
    
    # this is our client-handling thread
    def handle_client(client_socket):
          # print out what the client sends
          request = client_socket.recv(1024)
          print '[*] Received: %s' % request
          # send back a packet
          client_socket.send('ACK!')
          client_socket.close()
    
    while True:
          client, addr = server.accept()
          print '[*] Accept connection from: %s:%d' % (addr[0], addr[1])
          # spin up our client thread to handle incoming data
          client_handler = threading.Thread(target=handle_client, args=(client,))
          client_handler.start()
    
    ## tcp_client.py
    #!/usr/bin/env python
    # coding=utf-8
    
    import socket
    target_host = '127.0.0.1'
    target_port = 6666
    
    # create a socket object
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    # connect the client
    client.connect((target_host, target_port))
    
    # send some data
    client.send('hehe, just for a test!')
    
    # receive some data
    response = client.recv(1024)
    
    print response
    

      4. 基于UDP的C/S模型

      4.1  创建一个UDP服务器

    ss = socket()                          # 创建一个服务器套接字
    ss.bind()                              # 绑定服务器套接字
    inf_loop:                              # 服务器无限循环
      cs = ss.recvfrom() / ss.sendto()    # 传输数据(接受/发送)
    ss.close()

      4.2 创建一个UDP客户端

    cs = socket()                           # 创建客户端套接字
    comm_loop:                              # 通信循环  
        cs.sendto() / cs.recvfrom()         # 传输数据(发送/接受)
    cs.close()                              # 关闭客户端套接字
    

      4.3 TCP的C/S套接字模型

      下面是一个简单的UDP套接字的服务端和客户端程序

    ## udp_server.py
    #!/usr/bin/env python
    # coding=utf-8
    
    from socket import *
    
    HOST = ''
    PORT = 6666
    ADDR = (HOST, PORT)
    
    server = socket(AF_INET, SOCK_DGRAM)
    server.bind(ADDR)
    
    while True:
        print '[*] Waiting for message...'
        data, addr = server.recvfrom(1024)
        print '[*] Received from: %s
    %s' % (addr, data)
        server.sendto('Recvice message ok!',addr)
    ## udp_client.py
    #!/usr/bin/env python
    # coding=utf-8
    
    from socket import *
    
    HOST = '127.0.0.1'
    PORT = 6666
    ADDR = (HOST, PORT)
    
    client = socket(AF_INET, SOCK_DGRAM)
    while True:
        data = raw_input('> ')
        if not data:
            break
        client.sendto(data,ADDR)
        data, ADDR = client.recvfrom(1024)
        if not data:
            break
        print data
    
    client.close()  

      

  • 相关阅读:
    css 左右两栏 左边固定右边自适应
    Oracle 执行长SQL
    Oracle 游标基础
    ERROR 000464: Cannot get exclusive schema lock. Either being edited or in use by another application
    MyEclipse 批量更新编码集
    使用Windows服务发布WCF服务【转载】
    JavaScript的陷阱【转载】
    JS图片切换带超链接
    新正则表达式
    asp.net垃圾代码之asp.net去掉垃圾代码,优化aspx页面性能的方法
  • 原文地址:https://www.cnblogs.com/lingerhk/p/4471826.html
Copyright © 2011-2022 走看看