任务描述
本关任务:为 WEB 服务器创建一个流式套接字对象。
相关知识
为了完成本关任务,你需要掌握:
套接字与套接字类型
如何创建套接字及绑定主机
如何设置监听
套接字
套接字(Socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将 I/O 插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是 IP 地址与端口 Port 的组合。
为了满足不同的通信程序对通信质量和性能的要求,网络系统提供了三种不同类型的套接字,以供用户在设计网络应用程序时根据不同的要求来选择。分别是:
流式套接字(SOCK-STREAM)。提供一种可靠的、面向连接的双向数据传输服务,实现了数据无差错、无重复的发送。流式套接字内设流量控制,被传输的数据看作是无记录边界的字节流。在 TCP/IP 协议簇中,使用 TCP 协议来实现字节流的传输,当用户想要发送大批量的数据或者对数据传输有较高的要求时,可以使用流式套接字。
数据报套接字(SOCK-DGRAM)。提供一种无连接、不可靠的双向数据传输服务。数据包以独立的形式被发送,并且保留了记录边界,不提供可靠性保证。数据在传输过程中可能会丢失或重复,并且不能保证在接收端按发送顺序接收数据。在 TCP/IP 协议簇中,使用 UDP 协议来实现数据报套接字。在出现差错的可能性较小或允许部分传输出错的应用场合,可以使用数据报套接字进行数据传输,这样通信的效率较高。
原始套接字(SOCK-RAW)。该套接字允许对较低层协议(如 IP 或 ICMP )进行直接访问,常用于网络协议分析,检验新的网络协议实现,也可用于测试新配置或安装的网络设备。
如何创建套接字
在 Python 中使用套接字编程,需要先引入套接字(import socket);
使用 socket.socket() 函数来创建套接字。其语法如下:
socket(socket_family,socket_type,protocol=0)
'''
socket_family可以是如下参数之一:
AF_INET IPv4(默认)
AF_INET6 IPv6
AF_UNIX 只能够用于单一的Unix系统进程间通信
socket_type可以是如下参数之一:
SOCK_STREAM 流式socket , for TCP (默认)
SOCK_DGRAM 数据报式socket , for UDP
SOCK_RAW 原始套接字
'''
创建流式套接字示例:
mySocket = socket(AF_INET, SOCK_STREAM)
如何为套接字绑定主机及端口
一个完整的 Socket 可以用一个通信双方的相关描述:
{协议,本地地址,本地端口,远程地址,远程端口}
实际应用中,在创建一个 Socket 时先用一个半相关描述(服务器这一半可以确定,而另一半尚不确定):
{协议,本地地址,本地端口}
每一个 Socket 有一个本地的唯一端口号,由操作系统分配。
绑定指为套接字绑定地址包含主机及其端口。 在 AF_INET 下,以元组(host,port)的形式表示地址。
host:用字符串表示主机的 IP 地址。表示本机‘’,也可用‘127.0.0.1’表示回环地址,或者主机的一般 IP 地址。
port:端口号,数字表示。1024 以下为系统约定,自定义的用 1024 以上。
绑定通过套接字的绑定方法 bind()来完成,输入参数为元组 (host,port)。 绑定示例:
mySocket.bind(('127.0.0.1',1234)) #绑定本地回环地址
mySocket.bind(('',1234)) #自动获取IP地址
如何设置套接字监听
服务器程序在调用创建套接字 socket()和绑定bind()之后需要处于监听状态,因为不知客户端什么时候开始进行请求连接。为此,需调用套接字的监听方法 listen()。 一个服务端可能同时面对多个客户端的连接请求,为此服务器程序需创建一个连接队列来保存的连接请求,并依次为连接请求建立相应连接。为此需设置队列的大小作为监听方法的参数。
监听示例:
mySocket.listen(10) #设置连接队列大小为10,并使套接字处于监听状态。
编程要求
根据提示,在右侧编辑器代码的 Begin-End 之间补充代码:
创建一个流式套接字;
绑定本地地址‘127.0.0.1’,端口号为 6789;
使套接字处于监听状态,队列大小为 1。
测试说明
平台会对你编写的代码进行测试,输出套接字的相关属性。
预期输出:
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 6789)>
答案:
#import socket module
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
#Prepare a sever socket
########## Begin ##########
serverSocket.bind(('127.0.0.1',6789))
serverSocket.listen(1)
########## End ##########
print(serverSocket)
serverSocket.close()