概述
socket在所有编程语言的网络编程中都占有了举足轻重的角色,最基础也是最重要的角色。而Python也为它封装好了易用也比较完善的语法。
定义
socket翻译成中文的话叫做“孔”也可理解为“插座”的意思,是进程通信的一种机制。通常也称为“套接字”,用于描述IP地址和端口。可以用来实现不同虚拟机或者不同计算机之间的通信。一般情况下载网络主机上都会提供各种各样的服务,这些服务每个都开了一个socket并各自绑定一个端口号,不同的端口对应了不同的服务。
形象解释
以我们国家的电话网络为例,我们想象一下,在现实生活中我们打电话的流程是什么样子的?
- 拿起电话
- 拨通号码(如果不是同一地区,要在号码前加上区号)
- 如果对方空闲则接通,如果繁忙则提示“对不起,您拨打的电话正在通话中,请稍后再试”
好,现在我们弄清楚了现实中打电话的流程,我们对照这个流程来理解一下socket。上面说过socket是进程之间通信的一种机制。那么打电话的时候,打电话的这一方和接电话的那一方可以看做是两个不同的进程。这么说好理解吧?然后,电话号码中的区号就是socket中的网络地址,电话号码就是socket中的端口号。然后再回头看通话这个动作,打电话的这一方是不是要先拨通电话号码?这个拨打号码的动作我们可以把它理解为socket的发送连接请求。如果接电话那一方当前是空闲的,那么它就会接听电话,我们把这个动作看做是接收请求。至此电话双方就实现了通话,这个我们理解为传输数据。通话结束以后,一方挂断电话,我们就可以理解为是关闭了socket。
至此,我们就很直观的理解了,socket实质上提供了进程通信的端点。在进程通信之前,双方必须先建立各自的端点,否则没有办法建立连接。就好比要实现通话,你两个人必须都要有电话才行。
连接过程
根据上面的例子,这一方面就好理解多了。要想实现连接,在socket中分三步走:
1. 服务器监听:在服务器端并不会指定哪一个具体的客户端套接字来连接,而是长期处于监听状态,谁来请求,它就跟谁连接。
2. 客户端请求:客户端的套接字主动提起,并指出要连接服务器端的套接字地址和端口,然后提出连接请求。
3. 连接确认:当服务器端接收到这个请求之后,就会确认连接,这个时候就建立了一个线程,然后返回给客户端一个确认消息,客户端收到这个确认消息之后一旦认定,那么他们之间的连接就算建立成功了。
Python中的socket
好的,在上面我们搞明白了socket的原理之后,我们来看一下在Python中是怎么玩socket的。在Python当中创建套接字必须使用socket.socket()函数。
socket(socket_family,socket_type,protocol=0)
socket_family:
AF_UNIX:基于文件
AF_INET:基于网络iPv4(host,port)
AF_INET6:针对IPv6使用的(host, port, flowinfo, scopeid)
socket_type:
SOCK_STREAM:有连接的套接字(TCP)
SOCK_DFRAM:无连接的套接字(UDP)
protocol:
套接字协议
一般使用默认值,在这里我们暂且不论。
下面我们简单过下常见的套接字方法:(网上的表格,很适合我们现在看)
名称 | 描述 |
---|---|
服务器套接字方法 | |
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消息 |
a.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.setbliocking() | 设置套接字的阻塞或非阻塞模式 |
s.settimeout() | 设置阻塞套接字操作的超时时间 |
s.gettiemout() | 获取阻塞台阶自操作的超时时间 |
面向文件的套接字方法 | |
s.fileno() | 套接字的文件描述符 |
s.makefile() | 创建与套接字关联的文件对象 |
数据属性 | |
s.family | 套接字家族 |
s.type | 套接字类型 |
s.proto | 套接字协议 |
好了,这节就先到这里吧,下一节再在本节的基础上我们学一下怎么使用socket建立FTP网络小应用。
更多内容请关注公众号“计算机自学平台”