# ### 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模块详解的更多相关文章

  1. java网络编程Socket通信详解

    Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而在网络编程中,使用最多的就是Socket.像大家熟悉的QQ.MSN都使用了Socket相关的技术. ...

  2. python 网络编程--socket模块/struct模块

    socket模块: 客户端:CS架构,  client -> server 浏览器:BS架构,  browser -> server 网络通信本质:传输字节 doc命令查看ip地址:ipc ...

  3. (转)python标准库中socket模块详解

    python标准库中socket模块详解 socket模块简介 原文:http://www.lybbn.cn/data/datas.php?yw=71 网络上的两个程序通过一个双向的通信连接实现数据的 ...

  4. Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制

    Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制 JAVA 中原生的 socket 通信机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.co ...

  5. Java网络编程和NIO详解开篇:Java网络编程基础

    Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...

  6. Java网络编程和NIO详解8:浅析mmap和Direct Buffer

    Java网络编程与NIO详解8:浅析mmap和Direct Buffer 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NI ...

  7. Java网络编程和NIO详解9:基于NIO的网络编程框架Netty

    Java网络编程和NIO详解9:基于NIO的网络编程框架Netty 转自https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introd ...

  8. 铁乐学Python_Day33_网络编程Socket模块1

    铁乐学Python_Day33_网络编程Socket模块1 部份内容摘自授课老师的博客http://www.cnblogs.com/Eva-J/ 理解socket Socket是应用层与TCP/IP协 ...

  9. Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理

    Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...

随机推荐

  1. SpringMVC使用Redis共享session

    在使用之前,请确认项目已经整合了Redis 一.加入依赖 <dependency> <groupId>org.springframework.session</group ...

  2. less 学习笔记

    一.介绍 Less (Leaner Style Sheets 简洁的样式表) 是一门向后兼容的 CSS 预处理语言,它扩展了CSS 语言. less is more. 好处: 1.具有部分编程语言的功 ...

  3. 字节跳动——IT技术工程师面试题

    .自我介绍 .项目介绍 .争对个人项目进行提问 .场景模拟 .1如何知道用户的指定视频(类似于QQ发视频)的服务是正常的 .使用appum进行自动化测试 .使用bat脚本获取进程状态,然后定时发送em ...

  4. ServerSocket类的常用方法

    1.accept:侦听并接受此套接字的连接:此方法在连接传入之前一直阻塞. 2.setSoTimeout(timeout)方法的作用时设置超时时间,通过指定超时timeout值启用/禁用超时功能,以m ...

  5. ProjectServer2010升级到ProjectServer2016,Sharepoint2010升级到Sharepoint2016第一章

    之后还原 Project Server 2010 数据库和包含 Project Web App 网站数据的 SharePoint 内容数据库,您可以运行数据和 Project Web App 网站集升 ...

  6. 老师说的都对 - Beta阶段博客作业

    第二小组Beta冲刺阶段博客目录 github 地址:PCES-Github 一.Scrum Meeting 1.第十周会议记录 2.第十一周会议记录 3.第十二周会议记录 二.测试报告 Beta阶段 ...

  7. Quartznet速记

    参与 https://www.cnblogs.com/lzrabbit/archive/2012/04/14/2371420.html 1.XML配置 参考:https://www.cnblogs.c ...

  8. 数据结构导论 四 线性表的顺序存储VS链式存储

    前几章已经介绍到了顺序存储.链式存储 顺序存储:初始化.插入.删除.定位 链式存储:初始化.插入.删除.定位 顺序存储:初始化 strudt student{ int ID://ID char nam ...

  9. 第十六届浙江大学宁波理工学院程序设计大赛 D 雷顿女士与分队hard version(dp)

    题意 链接:https://ac.nowcoder.com/acm/contest/2995/D来源:牛客网 卡特莉接到来自某程序设计竞赛集训队的邀请,来为他们进行分队规划. 现在集训队共有n名选手, ...

  10. 删除文件linux

    bool LxDeleteFile(const char* src){ int32_t iRe = remove(src); ) return true; else return false; }