#!/usr/bin/env python
# -*- coding: utf-8 -*- import socket
from binascii import hexlify
import sys
# 对用户输入的命令行参数进行解析
import argparse # 先$ pip install ntplib 安装需要的python库文件
import ntplib
from time import ctime
import struct # python中每个函数之间要隔2行 # 发送数据缓冲区的大小
SEND_BUF_SIZE = 4096
# 接受数据缓冲区的大小
RECV_BUF_SIZE = 4096 NTP_SERVER = "0.uk.pool.ntp.org"
TIME1970 = 2208988800L def print_local_machine_infor():
"""打印本地主机名和本地主机的ip地址"""
host_name = socket.gethostname()
host_ip_address = socket.gethostbyname(host_name) print "Host name: %s" % host_name
print "Host ip address: %s" % host_ip_address def get_remote_machine_infor(remote_host_name="www.python.org"):
"""获取远程服务器的ip地址"""
try:
print "Remote ip address: %s" % socket.gethostbyname(remote_host_name)
except socket.error, err_msg:
print "%s: %s" % (remote_host_name, err_msg) def convert_ip4_address(ip_address):
# 将一个字符串IP地址转换为一个32位的网络字节序列(ascii码转二进制)
packed_ip_address = socket.inet_aton(ip_address)
# 将32位网络字节序列转换成字符串形式的ip地址(二进制转ascii码)
unpacked_ip_address = socket.inet_ntoa(packed_ip_address) # 将二进制数据的网络字节序列hexlify转换成16进制显示
print "Ip Address: %s => Packed: %s, Unpacked: %s" \
% (ip_address, hexlify(packed_ip_address), unpacked_ip_address) def find_service_name(protocol_name, port_number):
"""根据网络协议和端口号,获取服务名称"""
print "Port: %s => service name: %s" % (port_number, socket.getservbyport(port_number, protocol_name)) def convert_integer(port_number):
"""网络端口之间序列的转换"""
# 32-bit--将数据从网络字节序和主机字节序之间进行转换
print "Original: %s => Long host byte order: %s, Network byte order: %s" \
% (port_number, socket.ntohl(port_number), socket.htonl(port_number))
# 16-bit--将数据从网络字节序和主机字节序之间进行转换
print "Original: %s => Short host byte order: %s, Network byte order: %s" \
% (port_number, socket.ntohs(port_number), socket.htons(port_number)) def set_tcp_socket_timeout(wait_time):
"""设置tcp套接字的超时等待时间"""
# 创建流式tcp套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 打印套接字的默认的超时等待时间
print "Default socket timeout: %s" % s.gettimeout() # 设置套接字的超时等待时间
s.settimeout(wait_time)
print "Current socket timeout: %s" % s.gettimeout() def send_data_to_server():
# 构建命令行参数解释器
parser = argparse.ArgumentParser(description='Socket Error Examples')
# 添加命令行的可选输入参数
parser.add_argument('--host', action="store", dest="host", required=False)
parser.add_argument('--port', action="store", dest="port", type=int, required=False)
parser.add_argument('--file', action="store", dest="file", required=False) # 替换输入手动输入的命令行
given_args = parser.parse_args(["--host=www.python.org", "--port=80", "--file=Hello World"])
# 获取命令行输入的主机名
host = given_args.host
# 获取命令行输入的端口号
port = given_args.port
# 获取命令行输入的发送数据
filename = given_args.file # 创建tcp网络套接字
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, e:
# 打印创建网络套接字的错误
print "Error creating socket: %s" % e
# 退出进程
sys.exit(1) # 向指定的网络服务器发起网络连接
try:
s.connect((host, port))
except socket.gaierror, e:
print "Address-related error connecting to server: %s" % e
sys.exit(1)
except socket.error, e:
print "Connection error: %s" % e
sys.exit(1) try:
# 向指定的服务器发送数据请求
s.sendall("GET %s HTTP/1.0\r\n\r\n" % filename)
except socket.error, e:
print "Error sending data: %s" % e
sys.exit(1) # 循环输入服务器返回的数据
while 1:
# 接受请求服务器返回的数据
try:
buf = s.recv(2048)
except socket.error, e:
print "Error receiving data: %s" % e
sys.exit(1)
# 判断服务器返回的数据是否为null
if not len(buf):
break
# 将指定服务器返回的数据打印出来
sys.stdout.write(buf)
# 换行
sys.stdout.write("\r\n") def modify_buff_size():
# 创建流式tcp套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取套接字默认发送数据缓冲区的大小
bufsize = sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
print "Orig Send Buffer size [Before]:%d" % bufsize bufsize = sock.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)
print "Orig Recv Buffer size [Before]:%d" % bufsize # 设置网络套接字为非延迟模式
sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) # 设置网络套接字的发送数据缓冲区的大小
sock.setsockopt(
socket.SOL_SOCKET,
socket.SO_SNDBUF,
SEND_BUF_SIZE)
# 设置网络套接字的接受数据缓冲区的大小
sock.setsockopt(
socket.SOL_SOCKET,
socket.SO_RCVBUF,
RECV_BUF_SIZE) # 打印设置以后的网络套接字的发送数据缓冲区的大小
bufsize = sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
print "Send Buffer size [After]:%d" % bufsize # 打印设置以后的网络套接字的接受数据缓冲区的大小
bufsize = sock.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)
print "Recv Buffer size [After]:%d" % bufsize def reuse_socket_addr():
# 创建tcp流式套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取网络套接字默认的地址重用状态值
old_state = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
print "Old sock state: %s" % old_state # 设置网络套接字的地址重用状态的值为1即重用套接字地址
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 获取网络套接字的地址新的重用状态值
new_state = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
print "New sock state: %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(("127.0.0.1", local_port))
# 进行网络套接字的监听
srv.listen(1)
print ("Listening on port: %s " % local_port) while True:
# 接受客户端的网络连接
try:
connection, addr = srv.accept()
print 'Connected by %s:%s' % (addr[0], addr[1])
except KeyboardInterrupt:
break
except socket.error, msg:
print '%s' % (msg,) def test_socket_modes():
# 创建tcp网络套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置网络模式为阻塞模式
s.setblocking(1)
# 设置超时等待时间
s.settimeout(0.5) # 绑定ip地址和端口号
s.bind(("127.0.0.1", 0)) # 获取网路套接字的信息("ip地址", 端口号)
socket_address = s.getsockname()
# 打印网络套接字的名称
print "Trivial Server lauched on socket: %s" % str(socket_address) # 进行网络套接字的监听,等待客户端的连接
while 1:
s.listen(1) def print_ntp_time():
# 创建NTPClient实例对象
ntp_client = ntplib.NTPClient()
# 向NTP服务器发送时间请求
response = ntp_client.request('pool.ntp.org')
# 打印获取的时间
print "ntp time: "+str(ctime(response.tx_time)) def sntp_client():
# 创建udp套接字
client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM)
# 构建发送的数据包
data = '\x1b' + 47 * '\0'
# 将数据发送给服务器
client.sendto(data, (NTP_SERVER, 123))
# 获取服务返回的数据和ip地址(元组)
data, address = client.recvfrom(1024)
if data:
print 'Response received from:', address
# 解包服务返回的数据即时间
t = struct.unpack('!12I', data)[10]
# 减去从1970年1月1日对应的时间戳
t -= TIME1970 # 打印获取到的时间信息
print '\tTime=%s' % ctime(t) # 若当前模块,直接执行时,执行下面的代码
if __name__ == '__main__': # 打印本地主机的名称和ip地址
print_local_machine_infor() # 获取远程服务器的ip地址
get_remote_machine_infor() # 进行ip地址的转换
convert_ip4_address("192.168.0.1") # 通过端口号和协议,获取服务名称
for obj in [("tcp", 80), ("tcp", 25), ("tcp", 53)]:
find_service_name(obj[0], obj[1]) # 网络端口的字节序的转换
convert_integer(80) # 设置tcp套接字的超时等待时间
set_tcp_socket_timeout(10) # 向指定的服务发送数据
send_data_to_server() # 修改网路套接字的接受数据和发送数据的缓冲区的大小
modify_buff_size() # 打印ntp网络时间
print_ntp_time() # 获取当前时间
sntp_client() # 创建阻塞模式的服务器套接字
#test_socket_modes() # 重用套接字地址
reuse_socket_addr()

简单的网路连接服务端

#!/usr/bin/env python
# -*- coding: utf-8 -*- import socket
import argparse host = 'localhost'
data_payload = 2048
backlog = 5 def echo_server(port):
""" 简单的网络连接服务器 """
# 创建流式TCP网络套接字
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 # 绑定ip地址和端口
sock.bind(server_address)
# 进行网络套接字的监听
sock.listen(backlog) while True:
print "Waiting to receive message from client"
# 接受客户端的网络连接
client, address = sock.accept()
# 接受客户端发送来的数据
data = client.recv(data_payload) # 向客户端发送数据
if data:
print "Data: %s" % data
client.send(data)
print "sent %s bytes back to %s" % (data, address) # 关闭网络套接字
client.close() if __name__ == '__main__': # 构建命令行参数解释器
parser = argparse.ArgumentParser(description='Socket Server Example')
# 添加非可选参数--port(端口号)
parser.add_argument('--port', action="store", dest="port", type=int, required=False) # 解析用户输入的命令行参数
given_args = parser.parse_args(["--port=8777"])
# 获取网络连接的端口号
port = given_args.port # 创建网络连接的服务器
echo_server(port)

简单的网络连接客户端

#!/usr/bin/env python
# -*- coding: utf-8 -*- import socket
import argparse host = 'localhost' def echo_client(port):
""" 简单网络连接客户端 """
# 创建TCP流式网络套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 构建连接服务器的信息对象(ip地址,端口号)
server_address = (host, port)
print "Connecting to %s port %s" % server_address # 向服务器发起网络连接
sock.connect(server_address) try:
# 发送给服务器的数据
message = "Test message. This will be echoed"
print "Sending %s" % message # 向服务器发送数据信息
sock.sendall(message) amount_received = 0
# 期望收到服务器返回的数据长度
amount_expected = len(message)
# 循环获取服务器返回给客户端的数据
while amount_received < amount_expected:
# 获取服务器返回的数据
data = sock.recv(16)
amount_received += len(data)
print "Received: %s" % data
except socket.errno, e:
print "Socket error: %s" % str(e)
except Exception, e:
print "Other exception: %s" % str(e)
finally:
print "Closing connection to the server"
# 关闭网络套接字
sock.close() if __name__ == '__main__': # 构建命令行参数解释器对象
parser = argparse.ArgumentParser(description='Socket Server Example')
# 添加非可选的参数--port(端口号)
parser.add_argument('--port', action="store", dest="port", type=int, required=False) # 解析用户输入的命令行参数
given_args = parser.parse_args(["--port=8777"])
# 获取用户输入的网络端口号
port = given_args.port # 创建网络连接客户端
echo_client(port)

参考:《python网络编程攻略》

Python的套接字、IPv4和简单的客户端/服务器编程的更多相关文章

  1. Python之套接字

    Python之套接字 客户端Client/服务端Server架构: 1.硬件C/S架构 2.软件C/S架构 OSI4层:4层里有五层,五层里又有7层. 四层---------五层--------七层 ...

  2. Python Socket套接字编程

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...

  3. Python原始套接字编程

    在实验中需要自己构造单独的HTTP数据报文,而使用SOCK_STREAM进行发送数据包,需要进行完整的TCP交互. 因此想使用原始套接字进行编程,直接构造数据包,并在IP层进行发送,即采用SOCK_R ...

  4. python socket 套接字编程 单进程服务器 实现多客户端访问

    服务器: import socket #单进程服务器 实现多客户端访问 IO复用 #吧所有的客户端套接字 放在一个列表里面,一次又一次的便利过滤 server = socket.socket(sock ...

  5. python UDP套接字通信

    UDPserver.py import socket #导入套接字模块 s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # - socket.A ...

  6. Python原始套接字编程-乾颐堂

    在实验中需要自己构造单独的HTTP数据报文,而使用SOCK_STREAM进行发送数据包,需要进行完整的TCP交互. 因此想使用原始套接字进行编程,直接构造数据包,并在IP层进行发送,即采用SOCK_R ...

  7. Python Socket套接字

    socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Un ...

  8. Python socket套接字通信

    一.什么是socket? socket是一个模块, 又称套接字,用来封装 互联网协议(应用层以下的层). 二.为什么要有socket? socket可以实现互联网协议 应用层以下的层 的工作,提高开发 ...

  9. 基于TCP套接字实现的简单Demo

    由于代码的注释已经很详尽了,所以这里不再作过多说明.仅仅贴出代码和结果图. 值得注意的是必须先启动server程序再启动client. Server: #include <WINSOCK2.H& ...

随机推荐

  1. 《C++ Primer》笔记 第12章 动态内存

    shared_ptr和unique_ptr都支持的操作 解释 shared_ptr sp或unique_ptr up 空智能指针,可以指向类型为T的对象 p 将p用作一个条件判断,若p指向一个对象,则 ...

  2. PAT-1144(The Missing Number)set的使用,简单题

    The Missing Number PAT-1144 #include<iostream> #include<cstring> #include<string> ...

  3. ASP.NET Core重复读取Request.Body

    //HttpContext context.Request.EnableRewind(); //创建缓冲区存放Request.Body的内容,从而允许反复读取Request.Body的Stream u ...

  4. redis安装以及使用

    一.安装 1.源码安装 1.下载redis源码 $ wget http://download.redis.io/releases/redis-4.0.10.tar.gz 2.解压缩 $ tar -zx ...

  5. 2020 年安装 FreeBSD 系统的基础视频

    B 站搜索 BV14i4y137mh 包含了下载,虚拟机安装,配置 SSH 等教程. https://www.bilibili.com/video/BV14i4y137mh

  6. 解决springMVC https环境 jstlview redirect时变为http请求的问题

    <property name="redirectHttp10Compatible" value="false" />

  7. 常用开发库 - 告別BeanUtils拷贝,MapStruct工具库最全详解

    常用开发库 - MapStruct工具库详解 MapStruct是一款非常实用Java工具,主要用于解决对象之间的拷贝问题,比如PO/DTO/VO/QueryParam之间的转换问题.区别于BeanU ...

  8. 使用oracle序列+oracle定时任务获取每月从1开始的流水码

    --创建序列 --入库create sequence rk_seq;--出库create sequence ck_seq;--移库create sequence yk_seq; --创建存储过程 cr ...

  9. 利用浏览器favicon的缓存机制(F-Cache)生成客户端浏览器唯一指纹

    利用浏览器favicon的缓存机制(F-Cache)生成客户端浏览器唯一指纹 首先介绍下: 这个技术出自 UIC论文:https://www.cs.uic.edu/~polakis/papers/so ...

  10. 北航OO第三单元作业总结(3.1~3.3)

    JML简介及相关工具链使用 1.JML规格描述语言介绍 本单元学习的内容是JML规格描述语言.我们知道,面向对象方法是一个抽象过程,需求者仅需关注方法的规格.规格是对一个方法/类/程序的外部可感知行为 ...