首页 > 代码库 > 2017.07.09 Python网络编程之重用套接字地址

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=http://www.mamicode.com/‘/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=http://www.mamicode.com/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=http://www.mamicode.com/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网络编程之重用套接字地址