网络编程(1)

来源:互联网 发布:死神漫画单行本淘宝 编辑:程序博客网 时间:2024/06/16 20:39

一、套接字:通信端点

1.套接字
套接字是计算机网络数据结构,它体现了‘通信端点’的概念。在任何类型的通信开始之前,网络应用程序必须创建套接字。可以将他们比作电话插孔,没有它将无法通信。
套接字的起源可以追溯到20世纪70年代,它是加利福尼亚大学的伯克利版本UNIX的一部分。因此,有时套接字成为伯克利套接字或BSD套接字。
2.套接字地址:主机-端口对
如果一个套接字像一个电话插孔–允许通信的一些基础设备,那么主机名和端口号就像区号和电话号码的组合。然而,拥有硬件和通信的能力本身并没有任何好处,除非你知道电话打给谁,以及如何拨打电话。一个网络地址由主机名和端口号对组成,而这是网络通信所需要的。此外,并未事先说明必须有其他人在一端接听;否则,你将听到一个熟悉的声音‘您拨打的是空号,请稍后再拨’,有效的端口范围:0-65535(小于1024的端口号预留给了系统)


二、面向连接的套接字与无连接的套接字

1.面向连接的套接字(TCP)
面向连接的通信提供序列化的、可靠的和不重复的数据,而没有记录边界。这基本意味着每条消息可以拆分成多个片段,并且每一条消息片段都确保能够到达目的地,然后将他们按顺序组合在一起,最后将完整的消息传递给正在等待的应用程序。
实现这种连接类型的组要协议是传输控制协议(TCP)。为了创建TCP套接字,必须使用 SOCK_STREAM作为套接字类型。TCP套接字的名字SOCK_STREAM基于流套接字的一种表示。因为这些套接字(AF_INET)的网络版本使用因特网协议(IP)来搜索网络中的主机,所以整个系统通常结合这两种协议(TCP和IP)来进行。
2.无连接的套接字(UDP)
与虚拟电路形成鲜明对比的是数据报类型的套接字,它是一种无连接的套接字。这意味着,在通信开始之前并不需要创立连接。此时,在数据传输过程中并无法保证它的顺序性、可靠性、重复性。然而,数据报确实保存了边界记录,这意味着消息是以整体发送的,而并非首先分成多个片段。
使用数据报的消息传输可以比作邮政服务。信件和包裹或许并不能以发送顺序到达。事实上,它们可以不会到达。为了将其添加到并发通信中,在网络中甚至有可能存在重复的消息。
既然有这么多副作用,为什么还是用数据报呢?由于面向连接的套接字所提供的保证,因此它们的设置以及对虚拟电路的连接的维护需要大量的开销。然而数据报不需要这些开销,即它的成本更”廉价“,它们能提供更好的性能,并且可能适合一些类型的应用。
实现这种连接类型的主要协议是用户数据报协议(UDP),创建UDP套接字,必须使用SOCK_DGRAM作为套接字类型


三、python中的网络编程

1、socket的函数

内置函数:

**服务器套接字方法**----------s.bind()                     #将地址(主机名、端口号对)绑定到套接字上s.listen()                   #设置并启动TCP监听器s.accept()                   #被动接受TCP客户端连接,一直等待直到连接到达(阻塞)**客户端套接字方法**----------s.connect()                  #主动发起TCP服务端连接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.getsockopt()               #返回给定套接字选项的值s.setsockopt()               #设置给定套接字选项的值s.shutdown()                 #关闭连接s.close()                    #关闭套接字s.detach()                   #在未关闭文件描述符的情况下关闭套接                                                                      字,返回文件描述符s.ioctl()                    #控制套接字的模式(仅限windows)**面向阻塞的套接字方法** ----------s.setblocking()              #设置套接字的阻塞或非阻塞模式s.settimeout()               #设置阻塞套接字操作的超时时间s.gettimeout()               #获取阻塞套接字操作的超时时间**面向文件的套接字方法**----------s.fileno()                   #套接字的文件描述符s.makefile()                 #创建与套接字关联的文件对象**数据属性**----------s.family                     #套接字家族s.type                       #套接字类型s.proto                      #套接字协议         

示例1

#TCP服务端代码#!/usr/bin/pythonfrom socket import * from time import ctimeHOST = ''PORT = 21567BUFSIZE = 1024ADDR = (HOST,PORT)tcpSerSock = socket(AF_INET,SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)while True:       print 'waiting for connection...'       tcpCliSock,addr = tcpSerSock.accept()       print '...connected from: ',addr       while True:              data = tcpCliSock.recv(BUFSIZE)              if not data:                  break              tcpCliSock.send('[%s] %s' % (ctime(),data))       tcpCliSock.close()tcpSerSock.close()
#TCP客户端代码#!/usr/bin/pythonfrom socket import * HOST = 'localhost'PORT = 21567BUFSIZE = 1024ADDR = (HOST,PORT)tcpCliSock = socket(AF_INET,SOCK_STREAM)tcpCliSock.connect(ADDR)while True:       data = raw_input('> ')       if not data:            break       tcpCliSock.send(data)       data = tcpCliSock.recv(BUFSIZE)       if not data:           break       print datatcpCliSock.close()

示例2

#UDP服务端#!/usr/bin/pythonfrom socket import * from time import ctimeHOST = ''PORT = 21567BUFSIZE = 1024ADDR = (HOST,PORT)udpSerSock = socket(AF_INET,SOCK_DGRAM)udpSerSock.bind(ADDR)while True:       print 'waiting for messages...'       data,addr = udpSerSock.recvfrom(BUFSIZE)       udpSerSock.sendto('[%s] %s' % (ctime(),data),addr)       print '...received from and returned to:',addr udpSerSock.close()
#UDP客户端#!/usr/bin/pythonfrom socket import * HOST = 'localhost'PORT = 21567BUFSIZE = 1024ADDR = (HOST,PORT)udpCliSock = socket(AF_INET,SOCK_DGRAM)while True:       data = raw_input('> ')       if not data:            break       udpCliSock.sendto(data,ADDR)       data ,ADDR = udpCliSock.recvfrom(BUFSIZE)       if not data:           break       print dataudpCliSock.close()
原创粉丝点击