网络编程(1)

一、套接字:通信端点

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/python

from socket import * 
from time import ctime

HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (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/python

from socket import * 

HOST = 'localhost'
PORT = 21567
BUFSIZE = 1024
ADDR = (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 data
tcpCliSock.close()

示例2

#UDP服务端
#!/usr/bin/python

from socket import * 
from time import ctime

HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (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/python

from socket import * 

HOST = 'localhost'
PORT = 21567
BUFSIZE = 1024
ADDR = (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 data
udpCliSock.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值