Python 中的网络编程-socket模块创建TCP服务器创建TCP客户端
Posted yswyzh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 中的网络编程-socket模块创建TCP服务器创建TCP客户端相关的知识,希望对你有一定的参考价值。
Python 中的网络编程
二、创建TCP服务器
三、创建TCP客户端
套接字:
套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个 进程)与另一个运行的程序进行通信。这就是所谓的进程间通信(Inter Process Communication, IPC)。有两种类型的套接字:基于文件的和面向网络的。总的来说,Python 只支持 AF_UNIX、AF_NETLINK、AF_TIPC 和 AF_INET 家族。
socket()模块函数 要创建套接字,必须使用 socket.socket()函数,它一般的语法 :
1 socket(socket_family, socket_type, protocol=0)
其中,socket_family是AF_UNIX或AF_INET(如前所述),socket_type是SOCK_STREAM 或 SOCK_DGRAM(也如前所述)。protocol通常省略,默认为 0。
所以,为了创建 TCP/IP 套接字,可以用下面的方式调用 socket.socket()。
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
同样,为了创建 UDP/IP 套接字,需要执行以下语句。
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
因为有很多 socket 模块属性,所以此时使用“from module import *”这种导入方式可以 接受,不过这只是其中的一个例外。如果使用“from socket import *”,那么我们就把 socket 属性引入到了命名空间中。虽然这看起来有些麻烦,但是通过这种方式将能够大大缩短代码, 正如:
tcpSock = socket(AF_INET, SOCK_STREAM)
表格查询
名 字 | 描 述 |
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.makefile() | 创建与套接字关联的文件对象 数据属性 |
s.family | 套接字家族 |
s.proto | 套接字协议 |
创建通用 TCP 服务器的一般伪代码,然后对这些代码的含义进行一般 性的描述。
ss = socket() # 创建服务器套接字 ss.bind() # 套接字与地址绑定 ss.listen() # 监听连接 inf_loop: # 服务器无限循环 cs = ss.accept() # 接受客户端连接 comm_loop: # 通信循环 cs.recv()/cs.send() # 对话(接收/发送) cs.close() # 关闭客户端套接字 ss.close() # 关闭服务器套接字#(可选)
所有套接字都是通过使用 socket.socket()函数来创建的。因为服务器需要占用一个端口并 等待客户端的请求,所以它们必须绑定到一个本地地址。因为 TCP 是一种面向连接的通信系 统,所以在 TCP 服务器开始操作之前,必须安装一些基础设施。特别地,TCP 服务器必须监 听(传入)的连接。一旦这个安装过程完成后,服务器就可以开始它的无限循环。
接下来这个脚本创建一个TCP服务器,它接受来自客户端的消息,然后将消息加上时间戳前缀并发送回客户端
第 6~13 行 HOST 变量是空白的,这是对 bind()方法的标识,表示它可以使用任何可用的地址。我 们也选择了一个随机的端口号,并且该端口号似乎没有被使用或被系统保留。另外,对于该 应用程序,将缓冲区大小设置为 1KB。可以根据网络性能和程序需要改变这个容量。listen() 方法的参数是在连接被转接或拒绝之前,传入连接请求的最大数。 在第 11 行,分配了 TCP 服务器套接字(tcpSerSock),紧随其后的是将套接字绑定到服 务器地址以及开启 TCP 监听器的调用。
第 15~28 行 一旦进入服务器的无限循环之中,我们就(被动地)等待客户端的连接。当一个连接请求出 现时,我们进入对话循环中,在该循环中我们等待客户端发送的消息。如果消息是空白的,这意 味着客户端已经退出,所以此时我们将跳出对话循环,关闭当前客户端连接,然后等待另一个客 户端连接。如果确实得到了客户端发送的消息,就将其格式化并返回相同的数据,但是会在这些 数据中加上当前时间戳的前缀。
创建客户端比服务器要简单得多。
如:
cs = socket() # 创建客户端套接字 cs.connect() # 尝试连接服务器 comm_loop: # 通信循环 cs.send()/cs.recv() # 对话(发送/接收) cs.close() # 关闭客户端套接字
正如前面提到的,所有套接字都是利用 socket.socket()创建的。然而,一旦客户端拥有了 一个套接字,它就可以利用套接字的 connect()方法直接创建一个到服务器的连接。当连接建 立之后,它就可以参与到与服务器的一个对话中。最后,一旦客户端完成了它的事务,它就 可以关闭套接字,终止此次连接。
接下来这个脚本创建一个TCP客户端,它提示用户输入发送到服务器端的消息,并接收从服务器端返回的添加了时间戳前 缀的相同消息,然后将结果展示给用户。
第 1~3 行 在 UNIX 启动行后,从 socket 模块导入所有属性。 第 5~11 行 HOST 和 PORT 变量指服务器的主机名与端口号。因为在同一台计算机上运行测试(在 本例中),所以 HOST 包含本地主机名(如果你的服务器运行在另一台主机上,那么需要进 行相应修改)。端口号 PORT 应该与你为服务器设置的完全相同(否则,将无法进行通信)。 此外,也将缓冲区大小设置为 1KB。 在第 10 行分配了 TCP 客户端套接字(tcpCliSock),接着主动调用并连接到服务器。 第 13~23 行 客户端也有一个无限循环,但这并不意味着它会像服务器的循环一样永远运行下去。客户 端循环在以下两种条件下将会跳出:用户没有输入(第 14~16 行),或者服务器终止且对 recv() 方法的调用失败(第 18~20 行)。否则,在正常情况下,用户输入一些字符串数据,把这些数 据发送到服务器进行处理。然后,客户端接收到加了时间戳的字符串,并显示在屏幕上。在这个代码片段中,需要将本地主机修改成它的 IPv6 地址“::1”,同时请求套接字的 AF_INET6 家族。如果结合 tsTclnt3.py 和 tsTclntV6.py 中的变化,那么将得到一个 Python 3 版本的 IPv6 TCP 客户端。
以上是关于Python 中的网络编程-socket模块创建TCP服务器创建TCP客户端的主要内容,如果未能解决你的问题,请参考以下文章