socket 练习
1、什么是C/S架构?
C指的是client(客户端软件),S指的是Server(服务端软件)
2、互联网协议是什么?分别介绍五层协议中每一层的功能?
互联网协议:计算机界的英语 OSI七层: 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 TCP/IP四层/五层: 应用层 应用层 :软件 qq 暴风 传输层 传输层 :建立端口到端口的通信 0-65535 0-1023为系统占用端口 tcp ucp 网络层 网络层 :ip+mac 能找到全世界唯一的计算机 ip:找到哪一个局域网 mac:找到那一台机器 数据链路层 接口层 :定义电信号的分组方式 物理层 :发送01010101...电信号
3、基于tcp协议通信,为何建立链接需要三次握手,而断开链接却需要四次挥手
三次握手:client请求,server同意请求, client同意 四次挥手:client请求,server同意,server请求,client同意 因为:server有可能还有数据要发送
4、为何基于tcp协议的通信比基于udp协议的通信更可靠?
tcp: 可靠 对方给了确认收到信息,才发下一个,如果没收到确认信息就重发 udp: 不可靠 一直发数据,不需要对方回应
5、流式协议指的是什么协议,数据报协议指的是什么协议?
流式协议:TCP协议,可靠传输 数据报协议: UDP协议,不可传输
6、什么是socket?简述基于tcp协议的套接字通信流程
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。 socket == 片面说: ip + 端口 服务端:socket(),bind()绑定,listen()激活,accept(),recv(),send(),close() 客户端:socket(),connect(),send(),recv(),close()
7、什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?
粘包:数据粘在一起,主要因为:接收方不知道消息之间的界限,不知道一次性提取多少字节的数据造成的 数据量比较小,时间间隔比较短,就合并成了一个包,这是底层的一个优化算法(Nagle算法)
8、基于socket开发一个聊天程序,实现两端互相发送和接收消息
server
import socket chart = socket.socket(socket.AF_INET, socket.SOCK_STREAM) chart.bind(("127.0.0.1", 8080)) chart.listen(5) while True: # 循环链接 conn, addr = chart.accept() # 返回的是元组(客户端的信息,ip和端口号) while True: # 通讯循环 try: data = conn.recv(8096).decode("utf-8") # if not data: break # 仅适用于Linux操作系统(客户端断开),win 用try...except print(data) while True: msg = input(">>:").encode("utf-8") if 0 < len(msg) <= 8096: conn.send(msg) break else: print("文字太长") except ConnectionRefusedError: break
client
import socket chart = socket.socket(socket.AF_INET, socket.SOCK_STREAM) chart.connect(("127.0.0.1", 8080)) while True: while True: msg = input(">>:").encode("utf-8") if 0 < len(msg) <= 8096: chart.send(msg) break else: print("文字太长") data = chart.recv(8096).decode("utf-8") print(data)
9、基于tcp socket,开发简单的远程命令执行程序,允许用户执行命令,并返回结果
server
import socket import subprocess import struct cmd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) cmd.bind(("127.0.0.1", 8080)) cmd.listen(5) while True: conn, addr = cmd.accept() while True: try: command = conn.recv(1024).decode("utf-8") obj = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = obj.stdout.read() stderr = obj.stderr.read() result = stdout + stderr size = len(result) conn.send(struct.pack("i", size)) conn.send(result) except ConnectionRefusedError: break
client
import socket import struct dir = socket.socket(socket.AF_INET, socket.SOCK_STREAM) dir.connect(("127.0.0.1", 8080)) cmd = input(">>:").encode("utf-8") dir.send(cmd) size = struct.unpack("i", dir.recv(4))[0] recv_size = 0 recv_data = b"" while recv_size < size: res = dir.recv(1024) recv_data += res recv_size += len(res) print(recv_data.decode("gbk"))
10、基于tcp协议编写简单FTP程序,实现上传、下载文件功能,并解决粘包问题
11、基于udp协议编写程序,实现功能
a 、执行指定的命令,让客户端可以查看服务端的时间
server
import socket import time ser = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ser.bind(("127.0.0.1", 8080)) while True: data = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())).encode("utf-8") cmd, addr = ser.recvfrom(1024) if cmd.decode("utf-8") == "time": ser.sendto(data, addr)
client
import socket cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while True: cmd = input(">>:") cli.sendto(cmd.encode("utf-8"), ("127.0.0.1", 8080)) res, addr = cli.recvfrom(8096) print(res.decode("utf-8"))
b、执行指定的命令,让客户端可以与服务的的时间同步
server
import socket import subprocess import time server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server.bind(('127.0.0.1', 8080)) while True: data, client_addr = server.recvfrom(1024) print(data, client_addr) # obj = subprocess.Popen(data.decode('utf-8'),shell=True, # time 命令在windows 下不能用 # stdout=subprocess.PIPE, # stderr=subprocess.PIPE) # stdout = obj.stdout.read() # stderr = obj.stderr.read() # print(stdout+stderr) # server.sendto(stdout+stderr,client_addr) if data.decode('utf-8') == 'time': str_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # str_time = '2017-01-01 00:00:00' server.sendto(str_time.encode('gbk'), client_addr)
client
import socket import os import time client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while True: msg = input('>>>:').strip() client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080)) data, server_addr = client.recvfrom(1024) print(data.decode('utf-8'), server_addr) # localtime = time.localtime() # os.system("date %d-%d-%d" % (localtime.tm_year, localtime.tm_mon, localtime.tm_mday)) # 设置日期 # os.system("time %d:%d:%d.0" % (localtime.tm_hour, localtime.tm_min, localtime.tm_sec)) # 设置时间