服务器:
# -*- coding: utf-8 -*- import socket ''' 使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。 虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。 我们来看看如何通过UDP协议传输数据。和TCP类似,使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口 绑定端口和TCP一样,但是不需要调用listen()方法,而是直接接收来自任何客户端的数据 ''' # ipv4 SOCK_DGRAM指定了这个Socket的类型是UDP s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定 客户端口和地址: s.bind(('127.0.0.1', 9999)) print 'Bind UDP on 9999...' while True: # 接收数据 自动阻塞 等待客户端请求: data, addr = s.recvfrom(1024) print 'Received from %s:%s.' % addr s.sendto('Hello, %s!' % data, addr) #recvfrom()方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。客户端:
# -*- coding: utf-8 -*- import socket ''' 客户端使用UDP时,首先仍然创建基于UDP的Socket,然后,不需要调用connect(),直接通过sendto()给服务器发数据: ''' s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) for data in ['a', 'b', 'c']: # 发送数据: s.sendto(data, ('127.0.0.1', 9999)) # 接收数据: print s.recv(1024) s.close()------————————————————————————————————————
socket 常用函数
获取主机名和主机地址 socket.gethostname()
socket.gethostbyname()
import socket host = socket.gethostname() ip = socket.gethostbyname(host) # 还能够解析出外部服务的ip ip = socket.gethostbyname('www.baidu.com') 互转ipv4地址称32位二进制 socket.inet_aton()
socket.inet_ntoa()
import socket socket.inet_aton('127.0.0.1') socket.inet_ntoa('\x7f\x00\x00\x01') 指定端口和协议找服务名称 socket.getservbyport()
import socket # 找一下http和https的服务,如没有回返回notfound错误 socket.getservbyport(80, 'tcp') socket.getservbyport(443, 'tcp') 互转主机字节序和网络字节序 socket.ntohl()/socket.ntohs()
socket.htonl()/socket.htons()
套接字超时时间 socket.gettimeout()
socket.settimeout()
import socket # 设置一个套接字对象 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 超时时间默认为空 sock.settimeout(100) sock.gettimeout() 套接字异常 socket.error() 一般异常
socket.gaierror() 地址异常
socket.timeout() 超时异常
修改套接字缓冲区 socket.getsockopt()
socket.setsockopt()
import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 查询缓冲大小 sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF) sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF) # 设置大小 sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2048) sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2048) # 设置重用套接字 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 设置套接字阻塞模式 非阻塞:套接字遇到异常就抛错误socket.setblocking(0)
阻塞:遇到错误不会阻止操作socket.setblocking(1)
获取网络时间服务器时间(NTP proctol) import ntplib import time ntp = ntplib.NTPClient() res = ntp.request('pool.ntp.org') print time.ctime(res.tx_time) 练习套接字 客户端/服务端 简单通信
服务端
import socket # 初始化一个套接字 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置套接字可重用 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 绑定套接字 sock.bind(('localhost', 8888)) # 监听客户端链接,最大数目为5 sock.listen(5) while True: # 阻塞,接收 client, add = sock.accept() data = client.recv(2048) print "data:", data, '\n', 'host:', add, '\n' # 关闭 client.close 客户端
import socket # 初始化一个套接字 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 链接服务端 sock.connect(('localhost', 8888)) try: # 发送数据 sock.sendall("From client socket!") except socket.error, e: print "error!" finally: # 关闭 sock.close()