套接字的详细介绍会在另一篇博文指出,此片博文主要是python套接字的简单客户端编写。
两种套接字介绍:
- 面向连接的套接字:面向连接的套接字提供序列化,可靠的和不重复的数据交付。面向连接是可靠的传输,数据能够完成无误的传输到对方。传输数据时需要先建立连接(TCP的三次握手),然后传输数据。在编写套接字时使用参数 socket.SOCK_STREAM 来指定建立的TCP套接字对象
- 无连接的套接字:通信开始前不需要建立连接。数据传输过程中无法保持它的顺序性,可靠性和重复性。数据传输前,不用先建立连接。在编写套接字时使用参数 socket.SOCK_DGRAM 来指定建立UDP套接字对象。
TCP C/S编写:
服务端编写:(伪代码)
- 导入socket模块
- 建立对应的TCP 套接字对象
- 绑定要监听的主机和端口
- 开启监听,调用listen函数
- 开启和客户端的交互
客户端编写: (伪代码)
-
- 导入socket模块
- 建立对应的TCP 套接字对象
- 调用connect方法建立到server端的连接
- 进行和服务端的交互
通过实际例子来编写c/s端程序:
# *-* coding:utf-8 *-* # Auth: wangxz import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("localhost", 5969)) s.listen(5) while True: # 这个循环保证客户端退出后,可以有另一个客户端接入 tcp_server, addr = s.accept() # accept函数返回的是一个元组,一个是与客户端建立的新的tcp连接,另一个客户端连接的ip和端口 print("The client is %s at %s port " % addr ) # while True: # 这个循环保证每个客户端与服务持续交互 print("The communication system".center(50, "-")) data = tcp_server.recv(1024) if not data: break # 判断如果接收的数据为空,则跳出循环, # print(data.decode(encoding='ascii')) print(data) s.close()
# *-* coding:utf-8 *-* # Auth: wangxz import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("localhost", 5969)) while True: # 循环是客户端可以持续性输入 msg = raw_input("Please input your msg >>>: ") # msg = msg.encode() s.send(msg) #调用send方法发送数据
执行这段代码,可以多开启几个客户单程序,会发现只有第一个客户端可以与服务器通信,其余的客户端都是阻塞状态。当第一个断开连接之后,其余的客户端程序中的一个才会与服务端交互。
模仿写一个ssh命令的请求。
第1.0版本:
# *-* coding:utf-8 *-* # Auth: wangxz import socket import os import time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("localhost", 12345)) s.listen(5) while True: tcp_server, addr = s.accept() print("The connectios is from %s at %s port" % addr) while True: data = tcp_server.recv(1024) # 接收客户端的命令代码,然后执行,如果是空则退出循环 if not data: break tmp = os.popen(data, "r").read() # 调用popen()函数,执行shell命令,得到返回结果。 if not tmp: tcp_server.send("