2017.07.09 Python网络编程之重用套接字地址
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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*‘\\0‘
client.sendto(data,(NTP_SERVER,123))
data,address=client.recvfrom(1024)
if data:
print ‘接收数据来自:‘,address
t=struct.unpack(‘!12I‘,data)[10]
t-=TIME1970
print ‘\\t时间是:%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
以上是关于2017.07.09 Python网络编程之重用套接字地址的主要内容,如果未能解决你的问题,请参考以下文章