TCP中的粘包问题,以及用TCP和UDP实现多次聊天
TCP协议
在连接内多和客户端说几句
#server端
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()
while True
conn,addr = sk.accept()
while True
bad = input('>>>')
conn.send(bad.encode('utf-8'))
if bad.upper() == 'Q':
break
msg = conn.recv(1024).decode('utf-8')
if msg.upper == 'Q':break
print(msg)
conn.close() #挥手 断开连接
sk.close() #归还申请的操作系统资源
#client
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9001))
while True:
msg = sk.recv(1024)
msg2 = msg.decode('utf-8')
if msg2.upper == 'Q':break
print(msg2)
send_msg = input('>>>')
sk.send(send_msg.encode('uft-8'))
if send_msg.upper == 'Q':break
sk.close()
为什么要加while True
- 因为要进行多次通信
sk代表什么?
- sk代表启用的通信服务
conn代表什么?
- conn代表自己的IP地址,和对方的地址和端口
能够接受多个客户端的请求
- 为什么加while True
- 因为在一个客户端断开连接之后不能管不服务,要等待另一个客户端连接
- 怎么退出
- 在接收或者传输的时候先检查是不是要退出,要是退出的话就break
UDP协议
语法:
#server
import socket
sk = socket.socket(tyep = socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',9000))
msg,addr = sk.recvfrom(1024)
print(msg.decode('utf-8'))
msg = input('>>>')
sk.sendto(msg.encode('utf-8'),addr)
#client
import socket
sk = socket.socket(type = socket.SOCK_DGRAM)
server = ('127.0.0.1',9000)
while True:
msg = input('>>>')
if msg.upper == 'Q':break
sk.sendto(msg.encode('utf-8'),server)
msg = sk.recv(1024).decode('utf-8')
if msg.upper() == 'Q':break
print(msg)
涉及到的新方法
- type = socket.SOCK_DGRAM 在开启socket方法的时候加上这段代码,表示就是用UDP协议
- recvfrom:在server端接收信息的时候用recvfrom就可以把客户机的IP地址获取到
和TCP协议的区别
- 它可以同时建立多个连接,当一个连接断开后不会影响其他连接
粘包现象
- TCP协议的特点
- 多条消息之间没有边界,并且还有一大堆优化算法
- 什么叫做粘包
- 多条数据粘在一起
- 为什么会出现粘包
- 发送端:两条消息都很短,发送的间隔时间也非常短
- 接收端:多条消息由于没有及时接收,而在接收方的缓存短堆在一起导致粘包
- 怎么处理
#server
import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()
conn,addr = sk.accept()
msg1 = input('>>>').encode()
msg2 = input('>>>').encode()
blen = struct.pack('i',len(msg1))
conn.send(blen)
conn.send(msg1)
conn.send(msg2)
sk.close()
#cilent
import struct
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9001))
length = sk.recv(4)
length = struct.unpack('i',length)[0]
msg1 = sk.recv(length)
msg2 = sk.recv(1024)
print(msg1.decode('utf-8'))
print(msg2.decode('utf-8'))
sk.close()
什么叫自定义协议
- 在网络传输的时候,人为的为它定制一个协议,让它遵守此项协议
struct模块怎么用
- struct.pack()#将一个数字转换为4个字节的数
- struct.unpack()#将一个4个字节的数,转化回原来的数
osi五层协议
- 应用层
- 传输层
- tcp协议:效率低 面向连接、可靠、全双工的通信
- 三次握手
- 客户端向服务器端发送syn请求
- 服务器端向客户端回复ack并发送syn请求
- 客户端接收到的请求之后再回复ack表示建立连接
- 由客户端的connect + 服务端的 close
- 四次挥手
- 客户端向服务端发送fin请求
- 服务端回复ack确认
- 服务端向客户端发送fin请求
- 客户端回复ack
- 由客户端的close和服务端的close
- 三次握手
- udp协议:效率高 无连接的、不可靠
- 四层交换机,四层路由器
- tcp协议:效率低 面向连接、可靠、全双工的通信
- 网络层
- IP协议(ipv4,ipv6)
- 路由器、三层交换
- 数据链路层
- arp协议,地址解析协议 通过IP找到mac地址
- 物理层
TCP中的粘包问题,以及用TCP和UDP实现多次聊天的更多相关文章
- python socket的应用 以及tcp中的粘包现象
1,socket套接字 一个接口模块,在tcp/udp协议之间的传输接口,将其影藏在socket之后,用户看到的是socket让其看到的. 在tcp中当做server和client的主要模块运用 #s ...
- 第二十八天- tcp下的粘包和解决方案
1.什么是粘包 写在前面:只有TCP有粘包现象,UDP永远不会粘包 1.TCP下的粘包 因为TCP协议是面向连接.面向流的,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个 ...
- Netty 中的粘包和拆包
Netty 底层是基于 TCP 协议来处理网络数据传输.我们知道 TCP 协议是面向字节流的协议,数据像流水一样在网络中传输那何来 "包" 的概念呢? TCP是四层协议不负责数据逻 ...
- python中TCP协议中的粘包问题
TCP协议中的粘包问题 1.粘包现象 基于TCP实现一个简易远程cmd功能 #服务端 import socket import subprocess sever = socket.socket() s ...
- tcp协议传输中的粘包问题
什么是粘包问题 tcp是流体协议. 其nagle算法会将数据量较小. 并且发送间隔时间较短的多个数据包合并为一个发送. 网络传输的时候是一段一段字节流的发送. 在接收方看来根本不知道字节流从何开始. ...
- Linux 网络编程详解五(TCP/IP协议粘包解决方案二)
ssize_t recv(int s, void *buf, size_t len, int flags); --与read相比,只能用于网络套接字文件描述符 --当flags参数的值设置为MSG_P ...
- TCP通讯处理粘包详解
TCP通讯处理粘包详解 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据.TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的 ...
- Netty(三) 什么是 TCP 拆、粘包?如何解决?
前言 记得前段时间我们生产上的一个网关出现了故障. 这个网关逻辑非常简单,就是接收客户端的请求然后解析报文最后发送短信. 但这个请求并不是常见的 HTTP ,而是利用 Netty 自定义的协议. 有个 ...
- 什么是 TCP 拆、粘包?如何解决(Netty)
前言 记得前段时间我们生产上的一个网关出现了故障. 这个网关逻辑非常简单,就是接收客户端的请求然后解析报文最后发送短信. 但这个请求并不是常见的 HTTP ,而是利用 Netty 自定义的协议. 有个 ...
随机推荐
- [WPF]获取鼠标指针下的元素
原文:[WPF]获取鼠标指针下的元素 [WPF]获取鼠标指针下的元素 周银辉 以前写过一些GetElementUnderMouse之类的函数,要用到坐标换算而显得有些麻烦(特别是当元素有XXXTr ...
- OpenSSL RSA加解密 (.Net公钥加密/ Linux端私钥解密)
要求在.Net端生成公钥私钥对. 然后在.Net端使用RSA公钥加密:在Linux端使用RSA私钥解密. 最初的尝试是:.Net端使用RSACryptoServiceProvider; linux端使 ...
- sql学习目录
sql like N'%...%' 在C#里的写法 sql 循环 随机数创建数据 使用StringBuilder与SqlParameter 跨库查询数据 sql 多列求和 sql SCOPE_IDEN ...
- redis 从0 到 1 键值相关命令 服务器相关命令
keys * 获取所有的key 忽略其数据类型 数据为空 返回(empty list or set) keys a* .*b 获取以a开头 或者 以b结尾的key 返回(empty list ...
- Android疑难杂症之Theme
背景:最近在把自己之前写的一个应用换成Material Design风格,在看官方Guide后动手试了一试,没想到出门就遇到了坑,在换成Material Design风格的主题后,我设置了一下colo ...
- ArrayList(1.8)
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...
- Windows线程生灭(图文并茂)
一.线程创建 Windows线程在创建时会首先创建一个线程内核对象,它是一个较小的数据结构,操作系统通过它来管理线程.新线程可以访问进程内核对象的所有句柄.进程中的所有内存及同一进程中其它线程的栈. ...
- 使用AnimateWindow来实现窗口淡入淡出(主要有四种动画,滚动,滑动,折叠或展开,和淡入淡出)
如果是在VC6下进行编译,应引入下面的预编译宏,注意放在windows.h的前面#undef WINVER #define WINVER 0x500为什么要引入上面的宏呢?看看winuse ...
- 做了一个浏览指定文件格式的 TreeView(方便查看Source目录下的源码)
unit DirTreeView; interface uses SysUtils, Classes, Controls, Forms, ComCtrls; type TDirTreeView ...
- Linux用户和权限
用户和用户组管理 linux使用用户和组来限制资源的使用. 在linux上运行任何程序或命令都要以一个具体的用户来运行,这个用户的权限决定了相应的程序能访问的资源和能执行的操作. 用户相关命令 组是用 ...