tcp 实现聊天功能

server端

import socket

sk = socket.socket()

sk.bind(('127.0.0.1',22000))

sk.listen()

while True: #同时连多个人

obj,addr = sk.accept() #三次握手在这里完成

while True:

msg = input('>>>')

if msg.upper() == 'Q':break

obj.send(msg.encode('utf-8'))

content = obj.recv(1024).decode('utf-8')

print(content)

obj.close()

sk.close()

client端

import socket

sk = socket.socket() #实例化socket对象

sk.connect(('127.0.0.1',22000)) #生成连接

while True:

content = sk.recv(1023).decode('utf-8') #接受内容

print(content) #打印内容

msg = input('>>>')

if msg.upper() == 'Q':break

sk.send(msg.encode('utf-8')) #发送内容

sk.close() #关闭

udp 实现聊天功能

server端

import socket

sk = socket.socket(type=socket.SOCK_DGRAM)

sk.bind(('127.0.0.1',22000))

while True:

msg,addr = sk.recvfrom(1204)

print(msg.decode('utf-8'))

msg = input('>>>')

if msg.upper()=='Q':break

sk.sendto(msg.encode('utf-8'),addr)

sk.close()

client端

import socket

sk = socket.socket(type=socket.SOCK_DGRAM) #实例化socket对象

while True:

msg = input('>>>')

if msg.upper()=='Q':break

sk.sendto(msg.encode('utf-8'),('127.0.0.1',22000))

msg,addr = sk.recvfrom(1111)

print(msg.decode('utf-8'))

sk.close() #关闭

粘包现象

import socket

sk = socket.socket()

sk.bind(('127.0.0.1',9001))

sk.listen()

conn,addr = sk.accept()

conn.send(b'aa') #分别发送aa 和 bb

conn.send(b'bb')

conn.close()

sk.close()

import socket

import time

sk = socket.socket()

sk.connect(('127.0.0.1',9001))

time.sleep(0.1) #sleep 0.1s

msg1 = sk.recv(1024)

print(msg1) #b'aabb' 本来aa 和bb 应该分别在msg1 和msg2 打印出来的,现在放在一起打印了,就因为前面有了一个sleep了0.1秒,这就是粘包现象

msg2 = sk.recv(1024)

print(msg2) #b''

sk.close()

#粘包现象(只发生在tcp协议中)

#发生在发送端,消息很短,放在缓存池中,操作系统固定间隔再发送

#发生在接收端,接受不及时

#只发生在tcp协议,因为tcp协议多条消息之间没有边界,并且还有一大堆优化算法

#tcp协议中为什么存在没有边界,

#udp协议 网络最大带宽限制 MTU = 1500字节

#tcp没有上限,如果文件比较大,可以拆开

#解决粘包关键是设置边界

#【作业】 socket 发送文件

#治疗一下粘包

#server端

import socket

ipaddr = '127.0.0.1'

port = 10001

sk = socket.socket()

sk.bind((ipaddr,port))

sk.listen()

conn,addr = sk.accept()

msg1 = input('>>>').encode('utf-8') #输入‘你是猴子请来的救兵么’并转成bytes

msg2 = input('>>>').encode('utf-8') #输入‘是的’

num = str(len(msg1)) #计算第一次输入的字符串字节数,限制字节数为9999

print(num) #30 因为一个汉字utf-8 占3个字节,10个字

len1 = num.zfill(4) #补全数字到4位,client客户端就要先接收4位

conn.send(len1.encode('utf-8'))

conn.send(msg1)

conn.send(msg2)

conn.close()

sk.close()

#client端

import socket

import time

ipaddr = '127.0.0.1'

port = 10001

sk = socket.socket()

sk.connect((ipaddr,port))

time.sleep(0.2)

len1 = int(sk.recv(4).decode('utf-8')) #先接收4位

msg1 = sk.recv(len1).decode('utf-8')

msg2 = sk.recv(1024).decode('utf-8')

print(msg1) #打印 ‘你是猴子请来的救兵么’

print(msg2) #打印‘是的’

sk.close()

#以上就是我自定义的协议,第一次发送最多9999字节的字符串

#下面学习一个新的模块 struct

import struct

num1 = 129469649

num2 = 2342

num3 = 1

ret = struct.pack('i',num1) #i代表4个字节 b代表1个字节 H 和h 代表2个字节 d是8位

print(ret) #b'\xd1\x8c\xb7\x07' 4个字节

ret2 = struct.pack('i',num2)

print(ret2) #b'&\t\x00\x00' 4个字节

ret3 = struct.pack('i',num3)

print(ret3) #b'\x01\x00\x00\x00' 4个字节

#struct.pack() 可以把任意数字转成4个字节

#还可以转回来

print(struct.unpack('i',ret)) #(129469649,) 得到的是一个元组,第一个元素就是

print(struct.unpack('i',ret2)) # (2342,)

print(struct.unpack('i',ret3)) #(1,)

#那么上面的server端 自定义协议处,先发送字节就可以变更一下

#server端

import socket

import struct

ipaddr = '127.0.0.1'

port = 10001

sk = socket.socket()

sk.bind((ipaddr,port))

sk.listen()

conn,addr = sk.accept()

msg1 = input('>>>').encode('utf-8') #输入‘你是猴子请来的救兵么’并转成bytes

msg2 = input('>>>').encode('utf-8') #输入‘是的’

# num = str(len(msg1)) #计算第一次输入的字符串字节数,限制字节数为9999

# len1 = num.zfill(4) #补全数字到4位,client客户端就要先接收4位

blen = struct.pack('i',len(msg1))

# msg1是转成bytes后的类型,主要是先发到对方msg1的长度len(msg1)比如等于233,client端要先接收到233

# 然后根据233,recv(233)接收233个字节数的字节,再展示出来

# 我不能send一个len(msg1)这样的int数字过去,但是可以把len(msg1)用struct.pack()转成byte类型传过去,

# 过去之后再struct.unpack(),再转成int类型len1,送给recv(len1)

conn.send(blen) # 这里blen已经是bytes类型,就不用encode了

conn.send(msg1)

conn.send(msg2)

conn.close()

sk.close()

#client端

import socket

import struct

import time

ipaddr = '127.0.0.1'

port = 10001

sk = socket.socket()

sk.connect((ipaddr,port))

len1 = struct.unpack('i',sk.recv(4))[0]

#先接收4位byte类型,sk.recv(4) ,完了以后再把他struct.unpack()一下,得到是元组,取第一个元素[0],就是首先发过来的长度

#struct 可以一句话搞定自定义发送协议

msg1 = sk.recv(len1).decode('utf-8')

msg2 = sk.recv(1024).decode('utf-8')

print(msg1) #打印 ‘你是猴子请来的救兵么’

print(msg2) #打印‘是的’

sk.close()

#后续为了防止粘包,岂不是每次都要先发送长度,再根据长度接收内容?

#【练习】

#1、基于tcp协议的登陆认证:客户端输入用户名密码,发送到服务器端,服务器端认证,发送结果到客户端

#2、基于udp协议的多人聊天,自动识别用户 不能用ip和port

#3、基于tcp协议完成一个文件的上传,先处理小文件,在处理大文件

#4、选课系统

#总结

#tcp协议

#socket 模块引用

#sk的创建

#conn的创建

#接收多个客户端的请求,while True的位置

#怎么退出

#udp协议

#语法 socket创建的区别,加参数type

#涉及的发送和接收新方法 sendto recvfrom

#和tcp协议区别

#聊天程序

#粘包现象

#tcp协议的特点?三次握手连接,四次挥手断开

#什么是粘包,发送端发送数据频率高,下层来不及发送,固定时间间隔统一发送,接收端来不及接收

#怎么处理?先发送长度,根据长度接收内容

#自定义协议

#struct模块应用

#不用struct能不能自定义协议?根据发送字节长度int用zfill方法换算成固定字节长度的数值,传到接收端,接收端根据数值转成int,再根据int接收内容

pythonsocket自定义协议_小渣渣学习笔记 python day28【tcp聊天 udp聊天 粘包 自定义协议 struct模块】...相关推荐

  1. 69节入门python_小渣渣学习笔记 python day69 【Django】

    Django web框架本质 浏览器把你输入的网址,做成请求(请求头),如果是域名,通过dns解析服务器解析出对方服务器地址,然后把请求通过socket发送到对方地址,对方服务器socket接收到请求 ...

  2. 3gpp协议_【5G学习笔记】3GPP 5G协议分类清单大全

    " 本文对3GPP 5G协议进行了归类整理,以方便查阅.学习. 本文来源:网优雇佣军,如有侵权请联系删除" 3GPP中5G协议的归类整理,包括六部分,分别是:5G背景研究.5G接入 ...

  3. wxml 判断 小程序_小程序学习笔记之WXML

    1.数据绑定:{{}} a. 数据绑定使用 Mustache 语法(双大括号)将变量包起来,在对应的.js文件中写数据, b. 在.js中写一个值是否为boolean型,不要加上双引号 在.js中把对 ...

  4. 小程序学习笔记(1)

    小程序学习笔记(1) 以下是学习期间记录的笔记: 10-18号晚上学习笔记: 小程序实际上是需要下载安装的,只是很小,用户基本上觉察不到 组件是具有一定的功能的代码的集合 移动端适配: 物理像素:是图 ...

  5. 小程序 pagescrollto_微信小程序学习笔记(三)-- 首页及详情页开发

    一.常用组件 在上一个章节中讲解了封装请求数据的模块,在此处请求轮播图的数据 1.首页轮播图数据的请求以及渲染 1.1 轮播图数据的请求 pages/home/home.js import 2 使用组 ...

  6. 微信小程序学习笔记(1)

    微信小程序学习笔记 1.小程序代码结构 2.逻辑层和视图层 3. 小程序的宿主环境(通信模型.运行机制.组件.API) 4. 数据绑定和事件绑定 1.小程序代码结构 当开发者新建一个工程时,项目文件包 ...

  7. 自己的微信小程序学习笔记【3】——第三方UI库Lin-Ui的加载及使用

    其他微信小程序的学习笔记 自己的微信小程序学习笔记[1]--小程序开发工具的使用及项目文件说明 自己的微信小程序学习笔记[2]--从零开始新建项目 文章目录 其他微信小程序的学习笔记 前言 一.Lin ...

  8. 微信小程序学习笔记一 + 小程序介绍 前置知识

    微信小程序学习笔记一 1. 什么是小程序? 2017年度百度百科十大热词之一 微信小程序, 简称小程序, 英文名 Mini Program, 是一种不需要下载安装即可使用的应用 ( 张小龙对其的定义是 ...

  9. 微信小程序学习笔记(七)----简单文章推荐列表和分类图标的实现

    想要实现一个顶部是几篇纯文字的推荐文章,推荐文章下面是四个分类图标,具体实现出来是这个样子的,比较简单: 首先先来找一下素材,这几个图标是我在阿里巴巴图标库下载的,这里是下载地址: http://ww ...

最新文章

  1. UCSC hg19.ensembl.gtf
  2. 自己动手写一个Struts2
  3. CUDA与Java速度比较---生成Julia数据集并画图
  4. html2image api,图像标签_图像识别 Image_API参考_API_华为云
  5. R语言:ggplot2
  6. python之itemgetter函数:对字典列表进行多键排序
  7. 十大经典数据挖掘算法:SVM
  8. 翻译:Asp.net中多彩下拉框的实现
  9. 选择、插入、冒泡排序
  10. EasyNVR摄像机H5流媒体服务器在windows上批处理脚本自动以管理员权限运行
  11. 激活策略 查询_苹果手机未激活也可能不是原装货,激活过的手机到底能不能买?...
  12. 2021年上半年数据库系统工程师下午真题及答案解析
  13. 安卓QQ聊天记录导出、备份完全攻略
  14. ubuntu的不同版本
  15. qt报错:In included file: expected member name or ‘;‘ after declaration specifiers
  16. DCOM Access Denied 禁止访问的解决方法
  17. 传奇服务端服务端运行7个窗口的各窗口功能讲解
  18. 启智平台git使用指引
  19. flyme7 android彩蛋,Flyme 7内置彩蛋功能:520教你如何脱颖而出
  20. 编译原理 | 由正规式构造确定的有穷自动机DFA

热门文章

  1. C++工作笔记-getter/setter方法中大佬的风格
  2. mysql 归类函数_mysql常用的函数归类
  3. js小数运算出现多为小数问题_js 数字加减乘除精度问题,解决小数点后多位小数...
  4. java adapter 模式_Java设计模式之适配器模式(Adapter模式)介绍
  5. 【专栏必读】王道考研408操作系统万字笔记(从学生角度辅助大家理解):各章节导航及思维导图
  6. (软件工程复习核心重点)第一章软件工程概论-第四节:软件过程及相关模型
  7. c++ winpcap开发(4)
  8. C++中的深拷贝和浅拷贝(详解)
  9. 09. 用两个栈实现队列
  10. Python环境安装脚本,拷贝环境脚本,命令迁移模块(pip freeze requirements.txt)