1、什么是C/S架构?

客户端/服务器架构。实现服务端软件与客户端软件基于网络的通信。

2、互联网协议是什么?分别介绍五层协议中每一层的功能?

互联网协议是指用于互联网通信的规范。分为:osi七层、tcp/ip五层、tcp/ip四层

物理层:基于电气特性发送高低电压,高电压用1,低电压用0

数据链路层:通过Ethernet协议标准将电信号进行分组

网络层:引入一套新的地址用来区分不同的广播域/子网,这套地址即网络地址

传输层:建立端口到端口的通信,使用TCP/UDP协议

应用层:发起请求,使用http/ftp/自定义协议

3、基于tcp协议通信,为何建立链接需要三次握手,而断开链接却需要四次挥手

三次握手:首先客户端给服务端发送一个syn包请求连接;服务端收到之后会对客户端的请求作出回应,发送一个ack包给客户端,并且同时将一个syn包发送给客户端请求连接,即发送syn包+ack包;客户端收到syn包+ack包之后,对服务端的请求作出确认,发送一个ack包给服务端,此时,完成三次握手,客户端和服务端开始收发数据。

断开连接的时候,TCP也需要互相确认才可以断开连接,采用四次挥手断开一个连接,客户端如果发送完数据,就给服务端发送一个断开连接的请求,服务端收到请求后,给客户端发送一个确认信息,服务端接收完数据之后给客户端发送断开连接的请求,客户端收到消息后给服务端发送一个确认消息,至此,连接断开。

这样做的原因是,两端数据的接收并不是同时进行的,数据大小也不一样,如果三次挥手有可能导致一端的数据接收不完整。

4、为何基于tcp协议的通信比基于udp协议的通信更可靠?

tcp协议是面向链接的协议,在通信过程中,双方通过三次握手建立连接、四次挥手断开连接,发送方给接收方发送数据,如果没有得到接收方的回应,就会继续给它发消息,直到接收方回应。

udp是面向数据报的协议,不需要三次握手建立连接,它不会管接收方有没有收到数据。

5、流式协议指的是什么协议,数据报协议指的是什么协议?

流式协议指TCP协议,是通过三次握手建立连接再发送数据的,会存在粘包现象,当发送空消息时,对方并不会收到,不一定是一个send就要对应一个recv,传输效率低,网络开销大,可靠性高。

数据报协议是指UDP协议,是以消息为单位发送的数据的,一个sendto就对应一个recvfrom,不会存在粘包现象,即使发送空消息也能收到,传输效率高,网络开销小,可靠性低。

6、什么是socket?简述基于tcp协议的套接字通信流程

socket是介于应用层和传输层之间的一组接口。将复杂的TCP/IP协议封装到接口里面,使用者只需要知道怎么用即可,不需要关心底层的实现。

基于TCP的套接字通信流程:

1)服务端:创建一个套接字对象;绑定本机地址信息;开始时监听;接收连接;

2)客户端:创建套接字对象;主动连接客户端;等待对方接收

通过三次握手后建立连接,开始收发消息。

收发消息完了之后,通过四次挥手断开连接。

7、什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?

粘包是指两次命令执行的结果黏在一起。粘包发生在TCP协议中。

造成粘包的原因:接收方不知道所要接收消息的大小和界限。

发生粘包的情况:1、socket缓冲区导致,socket为了提高传输效率,往往会将较短时间间隔内较小的数据包合并发送,这样接收方就会收到一个粘包数据;

        2、接收方不知道该接收多大数据量,当接收方的最大接收量小于消息大小时,会发生粘包。

8、基于socket开发一个聊天程序,实现两端互相发送和接收消息

  1. # 服务端
  2. import socket
  3. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  4. server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
  5. server.bind(("127.0.0.1", 8080))
  6. server.listen(5)
  7. print("starting.....")
  8. while True:
  9. conn, client_addr = server.accept()
  10. if not conn:
  11. break
  12. while True:
  13. msg = conn.recv(1024)
  14. print("from aa:", msg.decode())
  15. if msg.decode() == "bye":
  16. break
  17. inp = input("me:").strip()
  18. conn.send(inp.encode())
  19. conn.close()
  20. server.close()
  21.  
  22. # 客户端
  23. import socket
  24. client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  25. client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  26. client.connect(("127.0.0.1", 8080))
  27. while True:
  28. msg = input("me:").strip()
  29. client.send(msg.encode())
  30. if msg == "bye":
  31. break
  32. msg1 = client.recv(1024)
  33. print("from xx:", msg1.decode())
  34.  
  35. client.close()

9、基于tcp socket,开发简单的远程命令执行程序,允许用户执行命令,并返回结果

  1. # 服务端
  2. import socket
  3. import subprocess
  4. import struct
  5. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  6. s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  7. s.bind(("127.0.0.1", 8080))
  8. s.listen(3)
  9. while True:
  10. print("starting....")
  11. conn,addr = s.accept()
  12. if not conn:
  13. break
  14. while True:
  15. cmd = conn.recv(1024).decode()
  16. if not cmd:
  17. break
  18. res = subprocess.Popen(cmd, stdout=subprocess.PIPE,
  19. stderr=subprocess.PIPE, shell=True)
  20. stdout = res.stdout.read()
  21. stderr = res.stderr.read()
  22. res_len = len(stdout)+len(stderr)
  23. len_struct = struct.pack("i", res_len)
  24. conn.send(len_struct)
  25. conn.send(stdout)
  26. conn.send(stderr)
  27. conn.close()
  28. s.close()
  29.  
  30. # 客户端
  31. import socket
  32. import struct
  33. c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  34. c.connect(("127.0.0.1", 8080))
  35. while True:
  36. cmd = input("input command:").strip()
  37. c.send(cmd.encode())
  38. if not cmd:
  39. break
  40. header = c.recv(4)
  41. header_len = struct.unpack("i", header)[0]
  42. res = c.recv(header_len)
  43. print("command results:", res.decode("gbk"))
  44. c.close()

10、基于tcp协议编写简单FTP程序,实现上传、下载文件功能,并解决粘包问题

  1. # 服务端
  2. import socket
  3. import os
  4. import json
  5. import struct
  6.  
  7. class Server:
  8. host = "127.0.0.1"
  9. port = 8080
  10. max_recv = 512
  11. serverfile = r"D:\code2\ex\删除\文件传输\server\serverfile"
  12.  
  13. def __init__(self):
  14. self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  15. self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  16. self.sock.bind((self.host, self.port))
  17. self.sock.listen(2)
  18.  
  19. def get(self, filename):
  20. """下载文件
  21. 制作报头,json,拿到报头大小,压缩报头长度为4,发送报头长度,发送报头,发送文件"""
  22. header_dic = {"filename": filename,
  23. "md5": "xxx",
  24. "file_size": os.path.getsize(os.path.join(self.serverfile, filename))}
  25. header_bytes = json.dumps(header_dic).encode()
  26. header_len = len(header_bytes)
  27. header_struct = struct.pack("i", header_len)
  28. self.conn.send(header_struct)
  29. self.conn.send(header_bytes)
  30. with open(os.path.join(self.serverfile, filename), "rb") as f:
  31. for line in f:
  32. self.conn.send(line)
  33.  
  34. def put(self, filename):
  35. """上传文件
  36. 拿到报头长度,解压报头长度,接收报头,json,拿到文件大小,接收文件"""
  37. header_struct = self.conn.recv(4)
  38. header_len = struct.unpack("i", header_struct)[0]
  39. header_bytes = self.conn.recv(header_len)
  40. header_dic = json.loads(header_bytes.decode())
  41. file_size = header_dic["file_size"]
  42. recv_size = 0
  43. with open(os.path.join(self.serverfile, filename), "wb") as f:
  44. while recv_size < file_size:
  45. content = self.conn.recv(self.max_recv)
  46. f.write(content)
  47. recv_size += len(content)
  48.  
  49. def run(self):
  50. while True:
  51. print("starting....")
  52. self.conn,self.addr = self.sock.accept()
  53. if not self.conn:
  54. break
  55. while True:
  56. cmd = self.conn.recv(self.max_recv).decode()
  57. if not cmd:
  58. break
  59. cmds = cmd.strip().split()
  60. if hasattr(self, cmds[0]):
  61. func = getattr(self, cmds[0])
  62. func(cmds[1])
  63. self.conn.close()
  64. self.sock.close()
  65.  
  66. server = Server()
  67. if __name__ == "__main__":
  68. server.run()
  69.  
  70. # 客户端
  71. import socket
  72. import os
  73. import json
  74. import struct
  75.  
  76. class Client:
  77. host = "127.0.0.1"
  78. port = 8080
  79. max_recv = 512
  80. localfile = r"D:\code2\ex\删除\文件传输\client\localfile"
  81.  
  82. def __init__(self):
  83. self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  84. self.sock.connect((self.host, self.port))
  85.  
  86. def get(self, filename):
  87. """下载文件
  88. 接收报头大小,解压报头大小,接收报头,json,
  89. 拿到文件大小,接收文件,存储文件
  90. """
  91. header_struct = self.sock.recv(4)
  92. header_len = struct.unpack("i", header_struct)[0]
  93. header_bytes = self.sock.recv(header_len)
  94. header_dic = json.loads(header_bytes.decode())
  95. file_size = header_dic["file_size"]
  96. recv_size = 0
  97. with open(os.path.join(self.localfile, filename), "wb") as f:
  98. while recv_size < file_size:
  99. content = self.sock.recv(self.max_recv)
  100. f.write(content)
  101. recv_size += len(content)
  102. print("下载成功!")
  103.  
  104. def put(self, filename):
  105. """上传文件
  106. 制作报头,json,压缩报头长度,发送报头长度,发送报头,发送文件"""
  107. header_dic = {"filename": filename,
  108. "md5":"xxxx",
  109. "file_size":os.path.getsize(os.path.join(self.localfile, filename))}
  110. header_bytes = json.dumps(header_dic).encode()
  111. header_len = len(header_bytes)
  112. header_struct = struct.pack("i", header_len)
  113. self.sock.send(header_struct)
  114. self.sock.send(header_bytes)
  115. with open(os.path.join(self.localfile, filename), "rb") as f:
  116. for line in f:
  117. self.sock.send(line)
  118. print("上传成功!")
  119.  
  120. def run(self):
  121. while True:
  122. cmd = input("input command:").strip()
  123. if not cmd:
  124. break
  125. cmds = cmd.split()
  126. if len(cmds) == 2 and hasattr(self, cmds[0]):
  127. self.sock.send(cmd.encode())
  128. func = getattr(self, cmds[0])
  129. func(cmds[1])
  130. self.sock.close()
  131.  
  132. client = Client()
  133. if __name__ == "__main__":
  134. client.run()

11、基于udp协议编写程序,实现功能

  1)执行指定的命令,让客户端可以查看服务端的时间

  2)执行指定的命令,让客户端可以与服务的的时间同步

  1. # 服务端
  2. import socket
  3. import time
  4. import subprocess
  5. server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
  6. server.bind(("127.0.0.1", 8080)) # 绑定IP、端口
  7. while True:
  8. cmd,addr = server.recvfrom(1024)
  9. if not addr:
  10. break
  11. print(cmd.decode(), addr)
  12. if cmd.decode() == "time": # 返回服务端时间
  13. time_now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) # 当前日期时间
  14. server.sendto(time_now.encode("gbk"), addr) # 发送
  15. else: # 解析命令
  16. obj = subprocess.Popen(cmd.decode(), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  17. stdout = obj.stdout.read()
  18. stderr = obj.stderr.read()
  19. server.sendto(stdout+stderr, addr)
  20. server.close()
  21.  
  22. # 客户端
  23. import socket
  24. client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  25. addr = ("127.0.0.1", 8080)
  26.  
  27. while True:
  28. cmd = input(">>>").strip()
  29. if not cmd:
  30. break
  31. client.sendto(cmd.encode(), addr) # 发送命令
  32. msg, addr_server = client.recvfrom(1024) # 接收消息
  33. print(msg.decode("gbk"))
  34. client.close()

python网络编程01的更多相关文章

  1. python网络编程01 /C/S架构|B/S架构、网络通信原理、五层协议、七层协议简述、端口映射技术

    python网络编程01 /C/S架构|B/S架构.网络通信原理.五层协议.七层协议简述.端口映射技术 目录 python网络编程01 /C/S架构|B/S架构.网络通信原理.五层协议.七层协议简述. ...

  2. python网络编程-01

    python网络编程 1.socket模块介绍 ①在网络编程中的一个基本组件就是套接字(socket),socket是两个程序之间的“信息通道”. ②套接字包括两个部分:服务器套接字.客户机套接字 ③ ...

  3. Python 网络编程(二)

    Python 网络编程 上一篇博客介绍了socket的基本概念以及实现了简单的TCP和UDP的客户端.服务器程序,本篇博客主要对socket编程进行更深入的讲解 一.简化版ssh实现 这是一个极其简单 ...

  4. Python 网络编程(一)

    Python 网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...

  5. Python学习(22)python网络编程

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

  6. Day07 - Python 网络编程 Socket

    1. Python 网络编程 Python 提供了两个级别访问网络服务: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口 ...

  7. 《Python网络编程》学习笔记--使用谷歌地理编码API获取一个JSON文档

    Foundations of Python Network Programing,Third Edition <python网络编程>,本书中的代码可在Github上搜索fopnp下载 本 ...

  8. Python网络编程基础pdf

    Python网络编程基础(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1VGwGtMSZbE0bSZe-MBl6qA 提取码:mert 复制这段内容后打开百度网盘手 ...

  9. python 网络编程(Socket)

    # from wsgiref.simple_server import make_server## def RunServer(environ,start_response):# start_resp ...

随机推荐

  1. EL表达式(详解)

    EL表达式 1.EL基本内容 1)语法结构        ${expression} 2)[]与.运算符      EL 提供.和[]两种运算符来存取数据.      当要存取的属性名称中包含一些特殊 ...

  2. bzoj1572 [Usaco2009 Open]工作安排Job【贪心 堆】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1572 尽管这一题没有看题解,但是耗时还是比本应耗费的时间要长,所以还是写一下,以提升经验 这 ...

  3. 加权平均值 WAvg”

    https://wenku.baidu.com/view/13d974fff8c75fbfc77db2d3.html

  4. jmeter(三)参数传递

    [一]参数化 录制脚本中有登录操作,需要输入用户名和密码,假如系统不允许相同的用户名和密码同时登录,或者想更好的模拟多个用户来登录系统. 这个时候就需要对用户名和密码进行参数化,使每个虚拟用户都使用不 ...

  5. WindowForm.计算器

    设计计算器: 外部变量: 数字键按钮: 运算符按钮事件代码: 清零按钮 等号按钮: 思维导图:

  6. java课程设计全程实录——第2天

    [反思] 今天主要完成JDBC数据的连接,查阅了大量博客和书籍,繁琐而细碎.但所幸还是连上了. [日常烦心事] 下午准备用idea连测试连接的,结果电脑跑不动....CPU一度100%居高不下,ide ...

  7. 虚拟机下安装 CentOS 7 的几个小问题

    ※ 网络问题(Destination Host Unreachable) 安装时网络选择的"桥接"模式, 安装完毕,并配置IP地址后,发现只能ping通自己,局域网内的其他IP无法 ...

  8. 开发小Tips

    Kotlin语言篇: 1.抽象类的定义 abstract class Person(var name : String, var age : Int) : Any() { abstract var a ...

  9. apache反向代理配置

    apache简单的反向代理配置 Proxypass /api /http://locahost:3000 反向代理-1.jpg

  10. Java MVC框架性能比较

    Java MVC框架性能比较 - by zvane 现在各种MVC框架很多,各框架的优缺点网络上也有很多的参考文章,但介绍各框架性能方面差别的文章却不多,本人在项目开发中,感觉到采用了struts2框 ...