一、理解socket
socket正如前文所说用于进程之间的通信,相当于是操作系统的I/O的延伸。
二、建立socket
先建立一个实际的socket对象,然后再将其连接到远程服务器。
建立socket对象时包含通信类型和协议家族。通信类型包括IPv4、IPv6、IPX/SPX(Netware)和AFP(Apple文件共享)。通常使用AF_INET,即IPv4。协议家族一般包括TCP通信的SOCK_STREAM和UDP通信的SOCK_DGRAM。连接对象时需提供一个包含远程主机名或IP地址和端口号的元组。对于不知道端口号的,可通过socket库的getservbyname函数来获得,格式为:socket.getservbyname(servicename[,protocolname]),服务名和协议名(tcp,udp)。
通过socket库来建立。类似如下:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(('www.baidu.com',80))
利用socket通信时可以用socket对象,也可以用文件对象。用socket对象的情况:读写数据时,需要协议可以详细地控制时、使用二进制协议传送固定大小数据时、数据超时需要特殊处理时,或是任何不止需要简单读写时,还有编写UDP程序时。而文件类对象一般用于面向线性的协议,只能用于TCP
socket模块的4种异常:
与一般I/O和通信问题有关的socket.error;与查询地址信息有关的socket.gaierror;与其他地址错误有关的socket.herror;与在一个socket调用settimeout()后,处理超时有关的socket.timeout
对于很多操作系统来说,又是在网络上发送数据的调用会在远程服务器收到信息前返回,因此可能有sendall成功调用返回但服务器收不到信息的情况发生。通过结束写操作后调用shutdown函数来解决。
三、总结
创建TCP客户端伪代码:
cs=socket() cs.connect() comm_loop: cs.send()/cs.recv() cs.close()
创建UDP客户端伪代码
ss=socket() ss.bind() inf_loop: cs=ss.recvfrom()/ss.sendto() ss.close()
socket对象方法:
函数 |
描述 |
服务器端套接字 |
|
s.bind() |
绑定地址(主机名,端口号名)到套接字,主机名必须是本机,可以为空,代表所有地址 |
s.listen() |
开始TCP监听,参数一般为5 |
s.accept() |
被动接受TCP客户端连接,(阻塞式)等待连接 ,参数为socket对象和(host,port)元组。 |
客户端套接字 |
|
s.connect() |
主动初始化TCP服务器连接,参数为(host,port) |
s.connect_ex() | 出错时返回出错码,而非抛出异常 |
公共的套接字 |
|
s.recv() |
接受数据,参数为buflen |
s.send() |
发送TCP数据,参数为data |
s.sendall() |
完整发送TCP数据 |
s.recvfrom() |
接受UDP数据,接受到的结果为data和发送者地址 |
s.sendto() |
发送UDP数据,参数为data和addr |
s.getpeername() |
连接到当前套接字的远端的地址, |
s.getsockname() |
当前套接字的地址 |
s.setsockopt() |
设置指定套接字的参数 |
s.close() |
关闭套接字 |
面向模块的套接字函数 |
|
s.setblocking() |
设置套接字的阻塞和非阻塞模式(0|1) |
s.settimeout() |
设置阻塞套接字操作的超时时间 |
s.gettimeout() |
得到阻塞套接字操作的超时时间 |
面向文件的套接字函数 |
|
s.fileno() |
套接字的文件描述符 |
s.makefile() |
创建一个与该套接字关联的文件对象 |
sendall()会循环调用send()函数,直到所有的数据都发送完毕。如果有错误会产生异常,但是无法直到发送了多少数据。
文件描述符是对应当前进程中打开的文件的整型表示。比如说标准输入的文件描述符是0,标准输出是1,标准错误是2,其他打开的文件依次为3,4.。。fileno()会获得与文件对象相关联的文件描述符。直接使用文件描述符会绕过文件对象的方法。一般用于os、socket、pipe等底层的操作。内核利用文件描述符来访问文件。文件描述符在形式上是一个非负整数。实际上它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。一些设计底层的程序会围绕文件描述符展开。文件描述符与包含相关信息(如文件的打开模式,文件的位置类型,文件的初始类型等)的文件对象相关联,这些信息被称作文件的上下文。