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 152. 乘积最大子序列
    leetcode 258. 各位相加 (python)
    leetcode 89. 格雷编码
    leetcode 62. 不同路径(C++)
    leetcode 142. 环形链表 II(c++)
    https证书制作及springboot配置https
    SpringBoot RestTemplate接收文件,并将文件发送到另外一个程序进行存储
    批量停止、删除docker容器
    记录Redis连接未正确释放,TCP连接过多,造成服务器上部分功能不可用和linux服务器内存一直增加问题
    外部连接mysql docker容器异常
  • 原文地址:https://www.cnblogs.com/hqutcy/p/7142121.html
Copyright © 2011-2022 走看看