python-网络编程socket模块详解
# ### tcp 循环发消息 import socket
# 1.创建一个对象
sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# 2.绑定ip,端口号,在网络上注册该主机
sk.bind( ("127.0.0.1",9004) )
# 3.监听端口
sk.listen() while True: # 4.建立三次握手
conn,addr = sk.accept()
# 5.收发数据的逻辑
# 该循环的作用:是循环发消息
while True:
# 接受消息
res = conn.recv(1024)
print(res.decode()) # 发送数据
strvar = input("请输入你要给对方的消息:")
conn.send(strvar.encode()) # 退出
if strvar == "q":
break # 6.四次挥手
conn.close()
# 7.退还端口
sk.close()
# ### tcp 客户端
import socket # 1.创建一个socket对象
sk = socket.socket() # 2.与服务器建立连接
sk.connect( ("127.0.0.1",9004) ) # 3.收发数据的逻辑 while True:
# 发送消息
strvar = input("请输入您要发送的消息:")
sk.send(strvar.encode())
# 接受消息
res = sk.recv(1024) if res == b"q":
break print(res.decode()) # 4.关闭连接
sk.close()
从上面的服务端与客户端我们可以知道,客户端无法单独存在,必须等待对应的服务端开启后才能与服务端开启通讯,而在TCP下的c/s模式下只能支持一客户端一服务器通话,而其他客户端连接进来无法做到实时通讯,必须等待前面的客户端断开连接后我才能与服务端交流,但同时也因为这个特性也早就了TCP下的传输数据稳定,不丢包等优点,缺点:速度慢连接拖拉
下面我们看看UDP下的socket是怎么样子的吧
服务端
# ### udp 服务端
import socket
# 1.创建一个socket对象
sk = socket.socket(type=socket.SOCK_DGRAM) # 2.绑定ip,端口号
sk.bind( ("127.0.0.1",9000) ) # 3.收发数据
# udp协议,如果作为服务器,第一次需要先接受消息,才能得到对方的ip和端口号
msg,cli_addr = sk.recvfrom(1024)
print(msg,cli_addr)
"""
b's9\xe6\x80\xbb\xe5\x86\xb3\xe8\xb5\x9b,lpl\xe5\x86\x8d\xe9\x80\xa0\xe8\xbe\x89\xe7\x85\x8c,\xe5\x87\xa4\xe5\x87\xb0\xe6\xb6\x85\xe6\xa7\x83' ('127.0.0.1', 53492)
"""
print(msg.decode()) # 发送数据给客户端
msg = "iG牛逼"
sk.sendto(msg.encode("utf-8"),cli_addr) # 4.关闭连接
sk.close()
客户端
# ### 客户端
import socket
# 1.创建socket对象
sk = socket.socket(type=socket.SOCK_DGRAM) # 2.收发数据
msg = "s9总决赛,lpl再造辉煌,凤凰涅槃"
# sendto(发送的二进制字节流消息,对方的ip和端口[元组])
sk.sendto(msg.encode("utf-8"),("127.0.0.1",9000)) # 接受数据
msg,addr = sk.recvfrom(1024)
print(msg.decode("utf-8"))
print(addr) # 3.关闭udp连接
sk.close
从上面我们可以看出,UDP协议下连接服务器时不会因为TCP的三次握手跟四次挥手而造成的连接拖沓,因为这个特点理论上可以同时又多个客户端同时连接服务器,而服务器可以同时给这些客户端提供服务,且不会理客户端的当前的连接状态,我只管发,但你收不收我不管,udp协议是基于这样的情况下运作的,那么UDP跟TCP的对比有啥优点呢?
快,不仅连接快,传输速度也快,但同时也造就了容易丢包,解决方法 创建缓存区,把数据一股气全部丢到缓存区里让客户端子去取,这样避免造成大面积丢包
这两种协议在传输数据时都存在黏包现象,为什么呢?
因为数据传输过程中服务端发送的太快,而客户端接收的太慢了,也就造成了数据黏包,从而造成数据紊乱,
解决这个问题有两个方案
(1)在服务端与客户端加延时可以避免黏包的现象发生
(2)把要传送的数据大小先发送给客户端,然后约定好每次发送多少,通过这样准确的发送与接收也可以避免黏包现象的发生
下面我通过代码来解释这个现象
# ### 黏包 服务端 import socket
import time
sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# 在网络上注册该主机
sk.bind( ("127.0.0.1",9001) )
# 监听端口
sk.listen()
# 三次握手
conn,addr = sk.accept()
# 处理收发数据的逻辑 # 在真正第一次发送数据之前,把真实的数据长度先发过去
conn.send("".encode()) # 第一次发送
msg = "hello," * 20
conn.send(msg.encode())
# time.sleep(0.1)
# 第二次发送
conn.send("world".encode()) # 四次挥手
conn.close()
# 退还端口
sk.close()
# ### 客户端 import socket
import time
# 创建一个tcp对象
sk = socket.socket()
# 连接服务器
sk.connect( ("127.0.0.1",9001) ) time.sleep(0.2) # 接受发送过来的真实的数据长度
res = sk.recv(8)
num = int(res.decode("utf-8"))
# 处理收发数据逻辑
res1 = sk.recv(num) # hello,
res2 = sk.recv(1024) # world
print(res1)
print(res2)
# 关闭链接
sk.close()
这是通过延时接收隔离了黏包现象,简单点就是接收速度变慢了
不推荐这种用法,影响效率
下面第二种
# ### 客户端 import socket
import time
# 创建一个tcp对象
sk = socket.socket()
# 连接服务器
sk.connect( ("127.0.0.1",9001) ) time.sleep(0.2) # 接受发送过来的真实的数据长度
res = sk.recv(8)
num = int(res.decode("utf-8"))
# 处理收发数据逻辑
res1 = sk.recv(num) # hello,
res2 = sk.recv(1024) # world
print(res1)
print(res2)
# 关闭链接
sk.close()
# ### 客户端
import socket
import struct sk = socket.socket()
sk.connect( ("127.0.0.1",9000) ) # 处理收发数据的逻辑
# 接受第一次发送过来的长度
n = sk.recv(4)
tup = struct.unpack("i",n)
n = tup[0]
print(n,type(n)) # 接受第二次发送过来的真实数据
res1 = sk.recv(n)
print(res1.decode("utf-8")) res2 = sk.recv(1024)
print(res2.decode("utf-8"))
# 关闭链接
sk.close()
这种就是我上面说的那样,通过先计算文件大小然后在跟客户端商量好每次发多少给你客户端接收多少,即避免了黏包,又提升力了效率
python-网络编程socket模块详解的更多相关文章
- java网络编程Socket通信详解
Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而在网络编程中,使用最多的就是Socket.像大家熟悉的QQ.MSN都使用了Socket相关的技术. ...
- python 网络编程--socket模块/struct模块
socket模块: 客户端:CS架构, client -> server 浏览器:BS架构, browser -> server 网络通信本质:传输字节 doc命令查看ip地址:ipc ...
- (转)python标准库中socket模块详解
python标准库中socket模块详解 socket模块简介 原文:http://www.lybbn.cn/data/datas.php?yw=71 网络上的两个程序通过一个双向的通信连接实现数据的 ...
- Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制
Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制 JAVA 中原生的 socket 通信机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.co ...
- Java网络编程和NIO详解开篇:Java网络编程基础
Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...
- Java网络编程和NIO详解8:浅析mmap和Direct Buffer
Java网络编程与NIO详解8:浅析mmap和Direct Buffer 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NI ...
- Java网络编程和NIO详解9:基于NIO的网络编程框架Netty
Java网络编程和NIO详解9:基于NIO的网络编程框架Netty 转自https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introd ...
- 铁乐学Python_Day33_网络编程Socket模块1
铁乐学Python_Day33_网络编程Socket模块1 部份内容摘自授课老师的博客http://www.cnblogs.com/Eva-J/ 理解socket Socket是应用层与TCP/IP协 ...
- Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理
Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...
随机推荐
- 【转】浅谈命令查询职责分离(CQRS)模式
原文链接:https://www.cnblogs.com/yangecnu/p/Introduction-CQRS.html 在常用的三层架构中,通常都是通过数据访问层来修改或者查询数据,一般修改和查 ...
- ZKWeb 官网与演示站点的部署步骤 (Linux + Nginx + Certbot)
因为没有给域名续费,加上私人时间不足,ZKWeb 的官网和演示站点已经停止了几个月的时间. 最近时间开始变多,所以重新购买了别的域名和服务器把官网和演示站点重新部署上去. 在此前站点是托管在共享主机上 ...
- 关于List和String有意思的几个应用
关于List和String有意思的几个应用 1. List:all_equal 功能:验证列表中的所有元素是否是都一样的. 解析:该技巧是使用[1:] 和 [:-1] 来比较所给定列表中的所有元素 ...
- IT兄弟连 HTML5教程 CSS3属性特效 文字描边
用CSS3实现的文字描边效果,一个CSS3文字特效实例,字体可以自己随意改,字体颜色也可以自己改.IE9以下浏览器无效果,所以提醒大家测试时候要使用Google Chrome.-webkit-text ...
- Mysql - 高可用方案之MM+Keepalived
一.概述 本文将介绍mysql的MM+Keepalived方案.该方案由两个mysql服务器组成,这两个mysql互为主备.其中一台主作为写服务器,另一台主作为读服务器.通过keepalived软件管 ...
- 一起学SpringMVC之文件上传
概述 在Web系统开发过程中,文件上传是普遍的功能,本文主要以一个简单的小例子,讲解SpringMVC中文件上传的使用方法,仅供学习分享使用,如有不足之处,还请指正. 文件上传依赖包 如下所示,文件上 ...
- Flask 教程 第十四章:Ajax
本文翻译自The Flask Mega-Tutorial Part XIV: Ajax 这是Flask Mega-Tutorial系列的第十四部分,我将使用Microsoft翻译服务和少许JavaSc ...
- Parallel.ForEach 使用多线遍历循环
Parallel.ForEach相对于foreach是多线程,并行操作;foreach是单线程品德操作. static void Main(string[] args) { Console.Write ...
- JavaScript 自定义html元素鼠标右键菜单
自定义html元素鼠标右键菜单 实现思路 在触发contextmenu事件时,取消默认行为(也就是阻止浏览器显示自带的菜单),获取右键事件对象,来确定鼠标的点击位置,作为显示菜单的left和top值 ...
- CSS入门(定位之浮动定位、伪类之鼠标悬停、光标修改和透明度修改和列表样式)
一.定位 所为定位,实际上就是定义元素框相对于其正常位置,应该出现在哪儿 定位就是改变元素在页面上的默认位置 分类: 普通流定位(元素默认的定位方式) 浮动定位 相对定位 绝对定位 固定定位 1.普通 ...