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 本系列文章首发于我的个人博 ...
随机推荐
- 初学Manjaro
近期,看有朋友在使用Manjaro系统,感觉这个系统挺不错,于是我也安装了Manjaro,学习一下!!!! Manjaro下载地址:https://manjaro.org/download/ Manj ...
- SpringBBoot整合MyBatis
一.目录展示 二.导入依赖 三.配置文件application.yml 四.Student实体类 package com.zn.entity; public class Student { priva ...
- 基于H7的中移动物联例子以及简易操作说明,方便电脑端和手机端远程查看数据
说明: 1.操作前,务必优先看此贴里面的基础例子,先将WIFI连接到路由器上,这样才可以访问外网: https://www.cnblogs.com/armfly/p/11307803.html 2.有 ...
- 使用系统定时器SysTick实现精确延时微秒和毫秒函数
SysTick定时器简介 SysTick定时器是存在于系统内核的一个滴答定时器,只要是ARM Cortex-M0/M3/M4/M7内核的MCU都包含这个定时器,它是一个24位的递减定时器,当计数到 0 ...
- C# get folder's Md5 generated by file's and filename's md5. get dictionary md5
C# get dictionary md5 static string GetDicMD5(string dirFullName) { logBuilder = new StringBuilder() ...
- [转载] redis学习入门 Redis 3.2.100
参考博客: https://blog.csdn.net/flyer_tang/article/details/80320974 https://blog.csdn.net/weixin_3077313 ...
- 使用shell脚本查看数据库负载情况
原创 Oracle 作者:jeanron100 时间:2014-05-23 08:56:26 8912 2 平时在查看数据库的问题时,会有种迷茫的感觉,如果没有任何人反馈问题,基本上没有主动查找问 ...
- 华为2019年NE40E-X8,承诺命令
commit每敲一行命令,都得确认一下.以防误操作.
- 史上最全Oracle数据泵常用命令
本文转自https://blog.csdn.net/Enmotech/article/details/102848825 墨墨导读:expdp和impdp是oracle数据库之间移动数据的工具,本文简 ...
- sql server数据库查询取出重复数据记录
问题:博主在2011年6月,广东技术师范大学大四的时候,从学校计算机科学学院网站看到招聘信息并到广东中原地产IT部面试,很清楚记得当时的面试题目:怎么从数据库里面查询重复记录. 解决方案:在sql s ...