python学习笔记(2)网络编程
2016-10-22 16:03
633 查看
套接字
套接字是计算机网络数据结构,网络应用程序必须创建套接字,没有套接字就无法进行网络通信。套接字最初出现在伯克利版本unix(BSD unix)中,是为了实现进程间的通讯。有两种类型的套接字,基于文件的和基于网络的,因为两个进程是在同一个计算机上的,所以这些套接字是基于文件的AF_LOCAL(AF_UNIX是AF_LOCAL的前身,python中任然在使用AF_UNIX)。不同主机间的通讯是基于网络的套接字AF_INET,(AF_INET6是基于IPv6寻址的版本)。python等大多数受欢迎的平台上都使用术语地址家族AF,但一些比较旧的系统可能会用协议家族PF。套接字地址:主机-端口对
一个网络地址由主机地址和端口号组成,有效的端口号地址是0-65535(0-1024端口号预留给系统),在POSIX兼容系统中,可以在/etc/services中找到预留的端口号列表(服务器/协议和套接字类型)。如下图:21号端口是tp服务,22号端口是ssh服务,23号端口是telnet服务
也可以在此网站中查看众所周知的服务端口号列表:http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
面向连接的套接字和无连接的套接字
不管采用哪种地址家族,都会有两种不同的套接字连接,面向连接的套接字(虚拟电路或流套接字)和无连接的套接字。面向连接的通信提供序列化的,可靠的和不重复的数据交付,但是没有边界记录,这种方式将数据差分成多个片段,确保每个片段都能够到达目的地,然后按顺序拼在一起,传递给应用程序。它是基于传输控制协议(TCP)实现的,为了创建TCP 套接字,必须使用SOCK_STREAM作为套接字类型。无连接的套接字(数据报类型套接字)它在通信开始之前并不需要建立连接,它无法保证顺序性,可靠性和重复性,但是它会记录边界信息,也就是信息是以整体的形式发送的而不是切分成片段。它不能保证数据能够成功到达,而且为了将其添加到并发通信中(同时和多个对象通信),在网络中也可能存在重复消息。UDP套接字的套接字类型是SOCK_DGRAM(datagram数据报)。python中的网络编程
套接字模块名为socket,所以在python网络编程中要先导入socket模块。创建套接字:socke(socket_family,socket_type,protocol)
其中socket_family是SOCKET_UNIX或SOCKET_IENT,socket_type是SOCKET_SRTEAM或SOCKET_DGRAM,protocol表示套接字协议,通常省略,默认为0。
常见的套接字内置方法和属性
服务器端: s.bind(addr) //将主机名和端口号绑定到套接字上 s.listen(int) //设置并启动tcp监听器,参数为在连接被拒绝或转接之前,传入连接请求的最大数 s.accept() //被动接受tcp客户端连接,一直等待直到连接到达(阻塞) 客户端: s.connect(addr) //连接到服务器 s.connect_ex() //connect 的扩展版本,此时会以错误码的形式返回问题,而不是抛出一个异常 普通的套接字方法: s.recv() //接收tcp消息 s.recv_into() //接收tcp消息到指定的缓冲区 s.send() //发送tcp消息 s.sendall() //完整地发送tcp消息 s.recvfrom() //接收udp消息 s.recvfrom_into() //接收udp消息到指定缓冲区 s.sendto() //发送udp消息 s.getpeername() //连接到套接字(tcp)的远程地址 s.getsockname() //当前套接字的地址 s.setsockopt() //返回给定套接字选项的值 s.setsockopt() //设置套接字选项的值 s.shotdown() //关闭连接 s.close() //关闭套接字 s.setblocking() //设置套接字的阻塞和非阻塞模式 s.makefile() //创建与套接字关联的文件对象
tcp套接字通信示例
server.py
__author__ = 'wenhai.dai' from socket import * import time import threading def tcplink(sock, addr): print('Accept new connection from %s:%s...' % addr) sock.send(b'Welcome!') while True: data = sock.recv(1024) time.sleep(1) if not data or data.decode('utf-8') == 'exit': break sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8')) sock.close() print('Connection from %s:%s closed.' % addr) tcpserv = socket(AF_INET, SOCK_STREAM) tcpserv.bind(('', 9999)) tcpserv.listen(5) while True: sock, addr = tcpserv.accept() t = threading.Thread(target=tcplink, args=(sock, addr)) t.start()
Accept new connection from 127.0.0.1:65211...
Connection from 127.0.0.1:65211 closed.
client.py
__author__ = 'wenhai.dai' import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 9999)) print(s.recv(1024).decode('utf-8')) for data in [b'Michael', b'Tracy', b'Sarah']: s.send(data) print(s.recv(1024).decode('utf-8')) s.send(b'exit') s.close()
Welcome!
Hello, Michael!
Hello, Tracy!
Hello, Sarah!
udp套接字通信示例
server.py
__author__ = 'wenhai.dai' from socket import * from time import ctime s = socket(AF_INET, SOCK_DGRAM) s.bind(('127.0.0.1', 12345)) while True: print('waiting for message...') data, addr = s.recvfrom(1024) s.sendto(ctime().encode('utf-8'), addr) if data.decode('utf-8') == 'exit': break print('receive from and return to :', addr) s.close()waiting for message...
receive from and return to : ('127.0.0.1', 63861)
waiting for message...
receive from and return to : ('127.0.0.1', 63861)
waiting for message...
receive from and return to : ('127.0.0.1', 63861)
waiting for message...
Process finished with exit code 0
client.py
__author__ = 'wenhai.dai' from socket import * c = socket(AF_INET, SOCK_DGRAM) ADDR = ('127.0.0.1', 12345) while True: data = input('>>') c.sendto(data.encode('utf-8'), ADDR) if data == 'exit': break data, addr = c.recvfrom(1024) if not data: pass else: print(data.decode('utf-8'), data) c.close()>>dai
Sat Oct 22 20:50:21 2016 b'Sat Oct 22 20:50:21 2016'
>>wen
Sat Oct 22 20:50:27 2016 b'Sat Oct 22 20:50:27 2016'
>>hai
Sat Oct 22 20:50:29 2016 b'Sat Oct 22 20:50:29 2016'
>>exit
Process finished with exit code 0
UDP通信和TCP通信的主要实现上的区别是UDP服务端不需要调用listen()函数来进行端口监听,服务端向客户端发送信息时调用服务端套接字对象的sendto()函数,把目标地址写在函数的参数中,而TCP实现是服务器端套接字对象的accept()函数返回客户端的套接字对象和地址,向客户端发送信息是调用客户端套接字对象的send()函数。在客户端的区别是UDP方式客户端套接字对象不需要调用connect()函数,地址都是在数据的发送和接受时作为参数来传递的。
相关文章推荐
- <<Python基础教程>>学习笔记 | 第14章 | 网络编程
- python 网络编程基础学习笔记(1)-网络客户端-socket
- 廖雪峰python学习笔记(1)--网络编程
- python基础教程_学习笔记24:网络编程、Python和万维网
- Python学习笔记(二)网络编程的简单示例
- Python学习笔记(4)-- 网络编程(1)-- socket
- Python学习笔记(五)——模块|图形界面|网络编程
- python 学习笔记12-----网络编程
- Python学习笔记--网络编程, socket
- python学习笔记(六)网络编程
- Python学习笔记(二)网络编程的简单示例
- Python学习笔记17:网络客户端编程
- Python学习笔记(七) -- Python Socket 网络编程
- Python学习笔记(十)——Python 网络编程
- Python学习笔记:网络编程(socket)
- Python之网络编程学习笔记
- python网络编程学习笔记(1)--网络编程背景
- 【Python】学习笔记——-17、网络编程
- Python学习笔记16:网络编程
- <<Python基础教程>>学习笔记 | 第14章 | 网络编程