博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络编程协议(TCP和UDP协议,粘包问题)以及socketserver模块
阅读量:7104 次
发布时间:2019-06-28

本文共 3104 字,大约阅读时间需要 10 分钟。

网络编程协议

1.osi七层模型

应用层  表示层  会话层  传输层  网络层  数据链路层  物理层

2.套接字 socket 

有两类,一种基于文件类型,一种基于网络类型

3.Tcp和udp协议

Tcp协议:面向连接,数据可靠,传输效率低,面向字节流

 建立连接与断开连接的过程(三次握手,四次挥手)

 建立连接(三次握手):

      1.客户端先发出消息到服务端,请求连接

      2.服务端收到信息后,给客户端反馈一个信息,等待客户端回复

      3.客户端收到服务端的反馈信息后,再像服务端发出收到消息,连接建立

 断开连接(四次挥手):

      1.客户端先发出消息到服务端,请求断开连接

      2.服务端先发送一个信息,让客户端进行等待服务端处理通道中的数据

      3.服务端处理完通道中的数据,给客户端发送一个信息,表示已经处理完数据,等待客户端回复

      4.客户端收到消息后,给服务端发送一个回复信息,服务端收到后,断开连接

tcp服务端

import socketserver = socket.socket()server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)ip_port = ("127.0.0.1",8004)server.bind(ip_port)server.listen(3)while 1:    conn,addr = server.accept()    while 1:        from_client_msg = conn.recv(1024)        from_client_str = from_client_msg.decode("utf-8")        print(from_client_str)        to_client_msg = input("服务输入")        conn.send(to_client_msg.encode("utf-8"))

tcp客户端

 

import socketclient = socket.socket()ip_port = ("127.0.0.1",8004)client.connect(ip_port)while 1:    to_server_msg = input("客户输入")    client.send(to_server_msg.encode("utf-8"))    from_server_msg = client.recv(1024)    print(from_server_msg.decode("utf-8"))

 

Udp协议:面向无连接,数据不可靠,传输效率高,面向报文

upd服务端

 

import socketudp_server = socket.socket(type=socket.SOCK_DGRAM)ip_port = ("127.0.0.1",8007)udp_server.bind(ip_port)from_client_msg,client_addr = udp_server.recvfrom(1024)udp_server.sendto(b"gun",client_addr)print(from_client_msg,client_addr)

 

upd客户端

 

import socketudp_client = socket.socket(type=socket.SOCK_DGRAM)ip_port = ("127.0.0.1",8007)udp_client.sendto(b"hello",ip_port)from_server_msg,server_addr = udp_client.recvfrom(1024)print(from_server_msg,server_addr)

 

现在多用Tcp协议,这个更安全,但是Tcp长连接有一些问题, 会出现粘包现象, 这种现象是由缓冲区引起的

缓冲区:  将程序和网络解耦

输入缓冲区

输出缓冲区

Import Subprocess

    sub_obj = subprocess.Popen(

        ‘dir’,

        shell=True,

        stdout=subprocess.PIPE,  #正确结果的存放位置

        stderr=subprocess.PIPE   #错误结果的存放位置

 )

4.粘包

两种粘包现象:

1 连续的小包可能会被优化算法给组合到一起进行发送

2 第一次如果发送的数据大小2000B,接收端一次性接受大小为1024B,这就导致剩下的内容会被下一次recv接收到,导致结果错乱

解决粘包的方法:

方案一:

由于双方不知道对方发送数据的长度,导致接收的时候,可能接收不全,或者多接收另外一次发送的信息内容,所以在发送真实数据之前,要先发送数据的长度,接收端根据长度来接收后面的真实数据,但是双方有一个交互确认的过程

方案二:

使用Struct模块,在发送前,把文件的大小打包,做成报头,把报头放在文件真实内容之前;在接收时,对发送过来的文件进行解包,然后打印文件真实内容.

打包:struct.pack(‘i’,长度)

解包:struct.unpack(‘i’,字节)

socketserver模块实现并发

  我们之前写的tcp协议的socket是不是一次只能和一个客户端通信,如果用socketserver可以实现和多个客户端通信。它是在socket的基础上进行了一层封装,也就是说底层还是调用的socket。后面我们要写的FTP作业,需要用它来实现并发,也就是同时可以和多个客户端进行通信,多个人可以同时进行上传下载等。

 

服务端代码

 

import socketserverclass Myserver(socketserver.BaseRequestHandler):    def handle(self):        while 1:            from_client_msg = self.request.recv(1024)            print(from_client_msg.decode("utf-8"))            msg = input("服务")            self.request.send(msg.encode("utf-8"))if __name__ == '__main__':    ip_port = ("127.0.0.1",8001)    server = socketserver.ThreadingTCPServer(ip_port,Myserver)    server.serve_forever()

 

 

客户端代码

import socketclient = socket.socket()client.connect(("127.0.0.1",8001))while 1:    client_msg = input("客户:")    client.send(client_msg.encode("utf-8"))    from_server_msg = client.recv(1024)    print(from_server_msg.decode("utf-8"))

 

转载于:https://www.cnblogs.com/fu-1111/p/10222622.html

你可能感兴趣的文章
222. Count Complete Tree Nodes
查看>>
ESMap+Html5+SpringBoot+FastDFS实现导航导购App
查看>>
Centos7下一键安装LNMP环境脚本
查看>>
vue-cli3环境变量与分环境打包
查看>>
用element的upload组件实现多图片上传和压缩
查看>>
在Linux Debian 8下部署基于PHP的Web项目。
查看>>
附实例!图解React的生命周期及执行顺序
查看>>
小程序瀑布流效果,解决左右两边高度差距过大的问题
查看>>
CentOS 7 更换 yum 源
查看>>
人工智能深度学习Caffe框架介绍,优秀的深度学习架构
查看>>
程序员编程10大哲理!血的教训,后人警惕!
查看>>
使用vue2+Axios遇到的一些坑
查看>>
解决 create-react-app IE 兼容性问题
查看>>
js数据结构-二叉树(二叉堆)
查看>>
都9102年了,还问Session和Cookie的区别
查看>>
this的指向(简单描述版)
查看>>
变量提升的原理
查看>>
【机器学习】机器学习简介
查看>>
我是如何在2年内逆袭成为BAT年薪40W的资深开发工程师的?
查看>>
当知识图谱遇上文本智能处理,会擦出怎样的火花?
查看>>