zoukankan      html  css  js  c++  java
  • 2017.07.09 Python网络编程之重用套接字地址

    1.重用套接字地址:

    # -*- coding: UTF-8 -*-
    # 如果在某个端口上运行一个Python套接字服务器,连接一次后便终止了运行,就不能在使用这个端口了
    # !usr/bin/env python
    # Python Network Programming Cookbook --Chapter -1
    # This program is optimized for Python 2.7
    # It may run on any other version with/without modifications

    import socket
    import sys

    def reuse_socket_addr():
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    old_state=sock.getsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR)
    print "旧的套接字状态是:%s" %old_state

    sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    new_state=sock.getsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR)
    print "新的套接字状态是:%s" %new_state

    local_port=8282

    srv=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    srv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    srv.bind(('',local_port))
    srv.listen(1)
    print "监听端口是:%s"%local_port

    while True:
    try:
    connection,addr=srv.accept()
    print "连接是被%s" %(addr[0],addr[1])
    except KeyboardInterrupt:
    break
    except socket.error,msg:
    print '%s' %(msg,)


    if __name__=='__main__':
    reuse_socket_addr()

    2.从网络时间服务器获取并打印当前时间:

    # -*- coding: UTF-8 -*-
    # 很多程序要求设备的时间准确,设备上的时间可能不够准确,需要和网络中的时间服务器同步,
    # 编写一个Python客户端,让设备上的时间和某个网络服务器同步,要完成这一步骤,需要使用ntplib,
    # 通过网络时间协议,即NTP处理客户端和服务器之间的通信,pip install ntplib
    # !usr/bin/env python
    # Python Network Programming Cookbook --Chapter -1
    # This program is optimized for Python 2.7
    # It may run on any other version with/without modifications

    import ntplib
    from time import ctime

    def print_time():
    ntp_client=ntplib.NTPClient()
    response=ntp_client.request('cn.pool.ntp.org')
    print ctime(response.tx_time)

    if __name__=='__main__':
    print_time()

    3.编写一个SNTP客户端(简单网络时间协议):

    # -*- coding: UTF-8 -*-
    # 有时不需要从NTP服务器上获取精确的时间,可以使用NTP的简化版,简单网络时间协议
    # !usr/bin/env python
    # Python Network Programming Cookbook --Chapter -1
    # This program is optimized for Python 2.7
    # It may run on any other version with/without modifications

    import socket
    import struct
    import sys
    import time

    NTP_SERVER="0.cn.pool.ntp.org"
    TIME1970=2208988800L

    def sntp_client():
    client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    data='x1b'+47*''
    client.sendto(data,(NTP_SERVER,123))
    data,address=client.recvfrom(1024)

    if data:
    print '接收数据来自:',address
    t=struct.unpack('!12I',data)[10]
    t-=TIME1970
    print ' 时间是:%s'%time.ctime(t)

    if __name__=='__main__':
    sntp_client()

     

    4.编写一个简单的回显客户端/服务器应用:

    服务器程序:

    # -*- coding: UTF-8 -*-
    # 这个例子中,不管服务器从客户端收到什么输入,都会将其回显出来,
    # 使用Python中的argparse模块,在命令行指定TCP端口服务器脚本和客户端脚本都要用到这个参数
    # !usr/bin/env python
    # Python Network Programming Cookbook --Chapter -1
    # This program is optimized for Python 2.7
    # It may run on any other version with/without modifications

    import socket
    import sys
    import argparse

    host='localhost'
    data_payload=2048
    backlog=5


    def echo_server(port):
    """一个简单的回显服务器应用"""
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    server_address=(host,port)
    print "Starting up echo server on %s port %s" %server_address

    sock.bind(server_address)
    sock.listen(backlog)
    port=int(port)
    while True:
    print "等待接收信息从Client"
    client,address=sock.accept()
    data=client.recv(data_payload)
    if data:
    print "Data:%s" %data
    print "发送%s 字节 返回给%s" %(data,address)
    client.send(data)
    client.close()

    if __name__=='__main__':
    parser=argparse.ArgumentParser(description='Socket Server Example')
    parser.add_argument('--port',action="store",dest="port",type=int,required=True)
    given_args=parser.parse_args()
    port=given_args.port

    echo_server(port)


    客户端程序:

    # -*- coding: UTF-8 -*-
    # 这个例子中,不管服务器从客户端收到什么输入,都会将其回显出来,
    # 使用Python中的argparse模块,在命令行指定TCP端口服务器脚本和客户端脚本都要用到这个参数
    # !usr/bin/env python
    # Python Network Programming Cookbook --Chapter -1
    # This program is optimized for Python 2.7
    # It may run on any other version with/without modifications

    import socket
    import sys

    import argparse

    host='localhost'

    def echo_client(port):
    """一个简单的回显消息的客户端"""
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server_address=(host,port)

    print "连接到服务器%s 的端口%s" %server_address
    sock.connect(server_address)

    try:
    message="Test message.This is will be echoed"
    print "发送消息%s" % message
    sock.sendall(message)


    amount_received = 0
    amount_excepeted = len(message)
    while amount_received < amount_excepeted:

    data=sock.recv(1024)

    print len(data)

    amount_received+=len(data)
    print amount_received
    print "Received data:%s" % data

    except socket.errno,e:
    print "Socket Error:%s" %str(e)

    except Exception,e:
    print "other exception: %s" %str(e)

    finally:
    print "Closeing Connection to the server"
    sock.close()



    if __name__=='__main__':
    parser=argparse.ArgumentParser(description='套接字服务案例')
    parser.add_argument('--port',action="store",dest="port",type=int,required=True)
    given_args=parser.parse_args()
    port=given_args.port
    echo_client(port)

    对python Socket的详细讲解:

      socket分为阻塞和非阻塞两种,可以通过setsockopt,或者更简单的setblocking, settimeout设置。
      阻塞式的socket的recv服从这样的规则:当缓冲区内有数据时,立即返回所有的数据;当缓冲区内无数据时,阻塞直到缓冲区中有数据。
      非阻塞式的socket的recv服从的规则则是:当缓冲区内有数据时,立即返回所有的数据;当缓冲区内无数据时,产生EAGAIN的错误并返回(在Python中会抛出一个异常)。两种情况都不会返回空字符串,返回空数据的结果是对方关闭了连接之后才会出现的。
     
      由于TCP的socket是一个流,因此是不存在“读完了对方发送来的数据”这件事的。你必须要每次读到数据之后,根据数据本身来判断当前需要等待的数据是否已经全部收到,来判断是否进行下一个recv。
     
    有一篇博文写的非常好,偶然发现,推荐给正在学习的大家:
    http://blog.csdn.net/rebelqsp/article/details/22109925
    
    
  • 相关阅读:
    【leetcode】416. Partition Equal Subset Sum
    【leetcode】893. Groups of Special-Equivalent Strings
    【leetcode】892. Surface Area of 3D Shapes
    【leetcode】883. Projection Area of 3D Shapes
    【leetcode】140. Word Break II
    【leetcode】126. Word Ladder II
    【leetcode】44. Wildcard Matching
    【leetcode】336. Palindrome Pairs
    【leetcode】354. Russian Doll Envelopes
    2017.12.22 英语面试手记
  • 原文地址:https://www.cnblogs.com/hqutcy/p/7142121.html
Copyright © 2011-2022 走看看