目录

1 TCP的三次握手四次挥手

1.1 三次握手

1 客户端向服务端发起SYN请求,请求建立连接,

2 服务端同意建立连接,回应ACK,同时服务端向客户端发起SYN请求

3 客户端回应ACK

1.2 四次挥手

挥手是任意的,客户端和服务端都可以首先断开连接

下面是以客户端发起的挥手

1 客户端发送完数据后发起FIN 请求,之后直接断开,
2 服务端返回一个ACK
3此时服务端还没有接收完数据,所以没有断开连接,接收完后,服务端想要断开,发送FIN

4 客户端返回ACK,结束

现实中的是TIME WAIT大量存在于服务端,是服务端主动断开连接,它在等待客户端发送ACK

总结

1 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的.

2 为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态

这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。

3 TIMEWAIT的作用?

主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒,因而,TIME_WAIT状态一般维持在1-4分钟。

[TCP资料](http://blog.csdn.net/u011726984/article/details/50781212

2 粘包现象

粘包存在两个方面,一个是服务端,一个是客户端

2.1 基于TCP制作远程执行命令操作(win服务端)

下面是服务端放在本地win平台,用127.0.0.1自己测试的代码

服务端

# coding:utf-8
# 基于TCP制作的远程执行命令的操作
# version;版本1
# 问题:有粘包现象 import socket
import subprocess phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None) # 买手机
# phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 就是它,在bind前加
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) phone.bind(('127.0.0.1', 8888)) # 绑定手机卡
phone.listen(5) # 开机 相当于挂起的电话连接 print("starting...") while True: # 通信循环
conn, addr = phone.accept() # 等待电话连接
while True: #
try: # 应对Windows系统 从缓存中读取空的情况
data = conn.recv(1024) # 收消息 从自己的缓存中找数据是最大的值
if not data:
continue # 应对Linux系统从缓存中读取空的情况
res = subprocess.Popen(
data.decode("utf-8"), shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE) # 把读取的信息存放在管道中
'''
# 这是判断错误的方式
err = res.stderr.read() # 首先判断错误信息
if not err: # 这是读取到的正常信息
res_cmd = res.stdout.read()
else:
res_cmd = err # 这是读取道的错误信息
conn.send(res_cmd) # 最后把接收到的数据发送到客户端
'''
# 这是直接发送的数据
res_err = res.stderr.read()
res_out = res.stdout.read()
conn.send(res_err)
conn.send(res_out)
except Exception:
break
conn.close() # 断开连接
phone.close() # 关闭服务器连接

客户端

import socket

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8888)) # 直接进行连接 while True:
cmd = input(">>:").strip() # 输入去除空格 换行
if not cmd:
continue # 没有输入内容 继续输入
# phone.send(cmd.encode("utf-8")) #
phone.send(bytes(cmd.encode("utf-8"))) # 默认发送的是字节bytes
data = phone.recv(1024) # 从客户端自己的缓存中寻找
print(data.decode('gbk')) # win 平台的默认编码是gbk 在Linux中用uft-8
phone.close() # 关闭客户端

实验的时候首先开启服务端,然后开启客户端

执行结果:

>>:cd
D:\Python\...\.... >>:listen
'listen' 不是内部或外部命令,也不是可运行的程序
或批处理文件。 >>:ls
'ls' 不是内部或外部命令,也不是可运行的程序
或批处理文件。 >>:tree
卷 我的小D 的文件夹 PATH 列表
卷序列号为 0005-B7F0
D:.
没有子文件夹
>>:hello
'hello' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
>>:

2.1 基于TCP制作远程执行命令操作(Linux服务端)

在Linux上需要修改IP地址位服务端的地址,客户端的解码方式修改成utf-8

服务端

# coding:utf-8
# 基于TCP制作的远程执行命令的操作
# version;版本1
# 问题:有粘包现象 具体看执行的结果 import socket
import subprocess phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None) # 买手机
# phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 就是它,在bind前加
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) phone.bind(('192.168.16.200', 8800)) # 修改成Linux自己的IP地址
phone.listen(5) # 开机 相当于挂起的电话连接 print("starting...") while True: # 通信循环
conn, addr = phone.accept() # 等待电话连接
while True: #
try: # 应对Windows系统 从缓存中读取空的情况
data = conn.recv(1024) # 收消息 从自己的缓存中找数据是最大的值
if not data:
continue # 应对Linux系统从缓存中读取空的情况
res = subprocess.Popen(
data.decode("utf-8"), shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE) # 把读取的信息存放在管道中
'''
# 这是判断错误的方式
err = res.stderr.read() # 首先判断错误信息
if not err: # 这是读取到的正常信息
res_cmd = res.stdout.read()
else:
res_cmd = err # 这是读取道的错误信息
conn.send(res_cmd) # 最后把接收到的数据发送到客户端
'''
# 这是直接发送的数据
res_err = res.stderr.read()
res_out = res.stdout.read()
conn.send(res_err)
conn.send(res_out)
except Exception:
break
conn.close() # 断开连接
phone.close() # 关闭服务器连接

客户端

# coding:utf-8

import socket

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.connect(("127.0.0.1", 8888)) # 直接进行连接
phone.connect(("192.168.16.200", 8800)) # Linux测试 while True:
cmd = input(">>:").strip() # 输入去除空格 换行
if not cmd:
continue # 没有输入内容 继续输入
# phone.send(cmd.encode("utf-8")) #
phone.send(bytes(cmd.encode("utf-8"))) # 默认发送的是字节bytes
data = phone.recv(1024) # 从客户端自己的缓存中寻找
# print(data.decode('gbk')) # win 平台的默认编码是gbk 在Linux中用uft-8
print(data.decode('utf-8')) # win 平台的默认编码是gbk 在Linux中用uft-8
phone.close() # 关闭客户端

执行结果

>>:pwd
/ >>:cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-bus-proxy:x:999:998:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:998:997:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
hzx:x:1000:1000::/home/hzx:/bin/bash
help:x:1001:1001::/home/hel
>>:ls # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!看下面的就是粘包
p:/bin/bash
egon:x:1002:1002::/home/egon:/bin/bash
tom:x:1004:1004::/home/tom:/bin/bash
jake:x:1005:1006::/home/jake:/bin/bash
rose:x:1006:1007::/home/rose:/bin/bash
nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin >>:ls # 现在才是正常执行的结果
bin
boot
dev
etc
FtpServer
hello.py
home
lib
lib64
media
mnt
opt
proc
Python-3.6.0
Python-3.6.0.tgz
root
run
sbin
sdb1
sdb2
sdb3
server.py
share
srv
sys
tail_new.py
tail.py
tartmp
test
test3
tmp
tmux
tmux-2.3
tmux-2.3.tar.gz
usr
var
>>:

2.2 粘包产生的原因:

上面出现了粘包的问题,粘包产生的主要原因是TCP协议是面向流(socket.SOCK_STREAM)),意思就是说发送端可以一个字节一个字节的发送, 软件的速度是大于网络的速度(网络有延迟),TCP把数据量小,时间间隔小的进行封包,一块发送,这就无法区分包的边界

接收端从自己的缓存中是有多少取多少,发送过来的是字节是没有边界的,所以收的时候是通过修改recv(1024)中的参数来增加一次性接收的值,但是这个如果是一个大文件的时候是有问题的,会全部去取到内存中,内存会爆。

所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。

3 解决粘包

类似以太网协议,在数据的前面加上固定长度的报头,报头中包含字节流的长度,然后一次send到对端。

对端在接收时,先从自己的缓存中取出定长的报头,然后再获取真实的数据

 解决粘包的最终版Linux服务端

 import socket
import subprocess
import json
import struct phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# phone.bind(('127.0.0.1', 8120))
phone.bind(('192.168.16.200', 8220)) phone.listen(5) print("sever is starting...")
while True: # 通信循环
conn, addr = phone.accept()
print(conn)
print(addr)
while True:
try:
data = conn.recv(1024) # conn.recv
if not data:
continue
res = subprocess.Popen(data.decode("utf-8"),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE) res_err = res.stderr.read()
res_out = res.stdout.read() # 数据长度
data_size = len(res_err) + len(res_out) # 制作报头
head_dic = {"data_size": data_size} # 把报头制作成字典格式
head_json = json.dumps(head_dic) # json 序列化
head_bytes = head_json.encode("utf-8") # 要发送需要转换成字节数据 # 1 发送报头的长度
head_len = len(head_bytes) # 这是报头的长度
conn.send(struct.pack("i", head_len)) # 2 发送报头
conn.send(head_bytes) # 3 发送真实的数据
conn.send(res_err)
conn.send(res_out) except Exception:
break
conn.close()
phone.close()

客户端

import socket
import json
import struct phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.connect(("192.168.16.200", 8120))
phone.connect(("192.168.43.20", 8220)) while True:
cmd = input(">>:").strip()
if not cmd:
continue
# phone.send(cmd.encode("utf-8"))
phone.send(bytes(cmd,encoding="utf-8")) # 1 接收报头长度
head_struct = phone.recv(4) # 先接收报头
head_len = struct.unpack("i", head_struct)[0] # 2 接收报头 head_bytes = phone.recv(head_len)
head_json = head_bytes.decode("utf-8")
head_dic = json.loads(head_json)
print(head_dic)
data_size = head_dic["data_size"] # 接收数据
recv_size = 0
recv_data = b''
while recv_size < data_size:
data = phone.recv(1024)
recv_size += len(data)
recv_data += data
print(recv_data.decode("utf-8")) phone.close()

解决粘包的最终版Linux服务端
```python
#
import socket
import subprocess
import json
import struct

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# phone.bind(('127.0.0.1', 8120))
phone.bind(('192.168.16.200', 8220))

phone.listen(5)

print("sever is starting...")
while True: # 通信循环
conn, addr = phone.accept()
print(conn)
print(addr)
while True:
try:
data = conn.recv(1024) # conn.recv
if not data:
continue
res = subprocess.Popen(data.decode("utf-8"),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)

res_err = res.stderr.read()
res_out = res.stdout.read()

# 数据长度
data_size = len(res_err) + len(res_out)

# 制作报头
head_dic = {"data_size": data_size} # 把报头制作成字典格式
head_json = json.dumps(head_dic) # json 序列化
head_bytes = head_json.encode("utf-8") # 要发送需要转换成字节数据

# 1 发送报头的长度
head_len = len(head_bytes) # 这是报头的长度
conn.send(struct.pack("i", head_len))

# 2 发送报头
conn.send(head_bytes)

# 3 发送真实的数据
conn.send(res_err)
conn.send(res_out)

except Exception:
break
conn.close()
phone.close()

```

客户端
```python
#
import socket
import json
import struct

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.connect(("192.168.16.200", 8120))
phone.connect(("192.168.43.20", 8220))

while True:
cmd = input(">>:").strip()
if not cmd:
continue
# phone.send(cmd.encode("utf-8"))
phone.send(bytes(cmd,encoding="utf-8"))

# 1 接收报头长度
head_struct = phone.recv(4) # 先接收报头
head_len = struct.unpack("i", head_struct)[0]

# 2 接收报头

head_bytes = phone.recv(head_len)
head_json = head_bytes.decode("utf-8")
head_dic = json.loads(head_json)
print(head_dic)
data_size = head_dic["data_size"]

# 接收数据
recv_size = 0
recv_data = b''
while recv_size < data_size:
data = phone.recv(1024)
recv_size += len(data)
recv_data += data
print(recv_data.decode("utf-8"))

phone.close()

```

:first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:3px}iframe{border:0}figure{-webkit-margin-before:0;-webkit-margin-after:0;-webkit-margin-start:0;-webkit-margin-end:0}kbd{border:1px solid #aaa;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:1px 2px 2px #ddd;-webkit-box-shadow:1px 2px 2px #ddd;box-shadow:1px 2px 2px #ddd;background-color:#f9f9f9;background-image:-moz-linear-gradient(top,#eee,#f9f9f9,#eee);background-image:-o-linear-gradient(top,#eee,#f9f9f9,#eee);background-image:-webkit-linear-gradient(top,#eee,#f9f9f9,#eee);background-image:linear-gradient(top,#eee,#f9f9f9,#eee);padding:1px 3px;font-family:inherit;font-size:.85em}.oembeded .oembed_photo{display:inline-block}img[data-echo]{margin:25px 0;width:100px;height:100px;background:url(../img/ajax.gif) center center no-repeat #fff}.spinner{display:inline-block;width:10px;height:10px;margin-bottom:-.1em;border:2px solid rgba(0,0,0,.5);border-top-color:transparent;border-radius:100%;-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}.spinner:after{content:'';display:block;width:0;height:0;position:absolute;top:-6px;left:0;border:4px solid transparent;border-bottom-color:rgba(0,0,0,.5);-webkit-transform:rotate(45deg);transform:rotate(45deg)}@-webkit-keyframes spin{to{-webkit-transform:rotate(360deg)}}@keyframes spin{to{transform:rotate(360deg)}}p.toc{margin:0!important}p.toc ul{padding-left:10px}p.toc>ul{padding:10px;margin:0 10px;display:inline-block;border:1px solid #ededed;border-radius:5px}p.toc li,p.toc ul{list-style-type:none}p.toc li{width:100%;padding:0;overflow:hidden}p.toc li a::after{content:"."}p.toc li a:before{content:"• "}p.toc h5{text-transform:uppercase}p.toc .title{float:left;padding-right:3px}p.toc .number{margin:0;float:right;padding-left:3px;background:#fff;display:none}input.task-list-item{margin-left:-1.62em}.markdown{font-family:"Hiragino Sans GB","Microsoft YaHei",STHeiti,SimSun,"Lucida Grande","Lucida Sans Unicode","Lucida Sans",'Segoe UI',AppleSDGothicNeo-Medium,'Malgun Gothic',Verdana,Tahoma,sans-serif;padding:20px}.markdown a{text-decoration:none;vertical-align:baseline}.markdown a:hover{text-decoration:underline}.markdown h1{font-size:2.2em;font-weight:700;margin:1.5em 0 1em}.markdown h2{font-size:1.8em;font-weight:700;margin:1.275em 0 .85em}.markdown h3{font-size:1.6em;font-weight:700;margin:1.125em 0 .75em}.markdown h4{font-size:1.4em;font-weight:700;margin:.99em 0 .66em}.markdown h5{font-size:1.2em;font-weight:700;margin:.855em 0 .57em}.markdown h6{font-size:1em;font-weight:700;margin:.75em 0 .5em}.markdown h1+p,.markdown h1:first-child,.markdown h2+p,.markdown h2:first-child,.markdown h3+p,.markdown h3:first-child,.markdown h4+p,.markdown h4:first-child,.markdown h5+p,.markdown h5:first-child,.markdown h6+p,.markdown h6:first-child{margin-top:0}.markdown hr{border:1px solid #ccc}.markdown p{margin:1em 0;word-wrap:break-word}.markdown ol{list-style-type:decimal}.markdown li{display:list-item;line-height:1.4em}.markdown blockquote{margin:1em 20px}.markdown blockquote>:first-child{margin-top:0}.markdown blockquote>:last-child{margin-bottom:0}.markdown blockquote cite:before{content:'\2014 \00A0'}.markdown .code{border-radius:3px;word-wrap:break-word}.markdown pre{border-radius:3px;word-wrap:break-word;border:1px solid #ccc;overflow:auto;padding:.5em}.markdown pre code{border:0;display:block}.markdown pre>code{font-family:Consolas,Inconsolata,Courier,monospace;font-weight:700;white-space:pre;margin:0}.markdown code{border-radius:3px;word-wrap:break-word;border:1px solid #ccc;padding:0 5px;margin:0 2px}.markdown img{max-width:100%}.markdown mark{color:#000;background-color:#fcf8e3}.markdown table{padding:0;border-collapse:collapse;border-spacing:0;margin-bottom:16px}.markdown table tr td,.markdown table tr th{border:1px solid #ccc;margin:0;padding:6px 13px}.markdown table tr th{font-weight:700}.markdown table tr th>:first-child{margin-top:0}.markdown table tr th>:last-child{margin-bottom:0}.markdown table tr td>:first-child{margin-top:0}.markdown table tr td>:last-child{margin-bottom:0}.github{padding:20px;font-family:"Helvetica Neue",Helvetica,"Hiragino Sans GB","Microsoft YaHei",STHeiti,SimSun,"Segoe UI",AppleSDGothicNeo-Medium,'Malgun Gothic',Arial,freesans,sans-serif;font-size:15px;background:#fff;line-height:1.6;-webkit-font-smoothing:antialiased}.github a{color:#3269a0}.github a:hover{color:#4183c4}.github h2{border-bottom:1px solid #e6e6e6;line-height:1.6}.github h6{color:#777}.github hr{border:1px solid #e6e6e6}.github pre>code{font-size:.9em;font-family:Consolas,Inconsolata,Courier,monospace}.github blockquote>code,.github h1>code,.github h2>code,.github h3>code,.github h4>code,.github h5>code,.github h6>code,.github li>code,.github p>code,.github td>code{background-color:rgba(0,0,0,.07);font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:85%;padding:.2em .5em;border:0}.github blockquote{border-left:4px solid #e6e6e6;padding:0 15px;font-style:italic}.github table{background-color:#fafafa}.github table tr td,.github table tr th{border:1px solid #e6e6e6}.github table tr:nth-child(2n){background-color:#f2f2f2}.hljs-comment,.hljs-title{color:#9c9491}.css .hljs-class,.css .hljs-id,.css .hljs-pseudo,.hljs-attribute,.hljs-regexp,.hljs-tag,.hljs-variable,.html .hljs-doctype,.ruby .hljs-constant,.xml .hljs-doctype,.xml .hljs-pi,.xml .hljs-tag .hljs-title{color:#f22c40}.hljs-built_in,.hljs-constant,.hljs-literal,.hljs-number,.hljs-params,.hljs-pragma,.hljs-preprocessor{color:#df5320}.css .hljs-rules .hljs-attribute,.hljs-ruby .hljs-class .hljs-title{color:#d5911a}.hljs-header,.hljs-inheritance,.hljs-string,.hljs-value,.ruby .hljs-symbol,.xml .hljs-cdata{color:#5ab738}.css .hljs-hexcolor{color:#00ad9c}.coffeescript .hljs-title,.hljs-function,.javascript .hljs-title,.perl .hljs-sub,.python .hljs-decorator,.python .hljs-title,.ruby .hljs-function .hljs-title,.ruby .hljs-title .hljs-keyword{color:#407ee7}.hljs-keyword,.javascript .hljs-function{color:#6666ea}.hljs{display:block;overflow-x:auto;background:#2c2421;color:#a8a19f;padding:.5em;-webkit-text-size-adjust:none}.coffeescript .javascript,.javascript .xml,.tex .hljs-formula,.xml .css,.xml .hljs-cdata,.xml .javascript,.xml .vbscript{opacity:.5}.MathJax_Hover_Frame{border-radius:.25em;-webkit-border-radius:.25em;-moz-border-radius:.25em;-khtml-border-radius:.25em;box-shadow:0 0 15px #83A;-webkit-box-shadow:0 0 15px #83A;-moz-box-shadow:0 0 15px #83A;-khtml-box-shadow:0 0 15px #83A;border:1px solid #A6D!important;display:inline-block;position:absolute}.MathJax_Hover_Arrow{position:absolute;width:15px;height:11px;cursor:pointer}#MathJax_About{position:fixed;left:50%;width:auto;text-align:center;border:3px outset;padding:1em 2em;background-color:#DDD;color:#000;cursor:default;font-family:message-box;font-size:120%;font-style:normal;text-indent:0;text-transform:none;line-height:normal;letter-spacing:normal;word-spacing:normal;word-wrap:normal;white-space:nowrap;float:none;z-index:201;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;-khtml-border-radius:15px;box-shadow:0 10px 20px gray;-webkit-box-shadow:0 10px 20px gray;-moz-box-shadow:0 10px 20px gray;-khtml-box-shadow:0 10px 20px gray;filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}.MathJax_Menu{position:absolute;background-color:#fff;color:#000;width:auto;padding:2px;border:1px solid #CCC;margin:0;cursor:default;font:menu;text-align:left;text-indent:0;text-transform:none;line-height:normal;letter-spacing:normal;word-spacing:normal;word-wrap:normal;white-space:nowrap;float:none;z-index:201;box-shadow:0 10px 20px gray;-webkit-box-shadow:0 10px 20px gray;-moz-box-shadow:0 10px 20px gray;-khtml-box-shadow:0 10px 20px gray;filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}.MathJax_MenuItem{padding:2px 2em;background:0 0}.MathJax_MenuArrow{position:absolute;right:.5em;color:#666}.MathJax_MenuActive .MathJax_MenuArrow{color:#fff}.MathJax_MenuArrow.RTL{left:.5em;right:auto}.MathJax_MenuCheck{position:absolute;left:.7em}.MathJax_MenuCheck.RTL{right:.7em;left:auto}.MathJax_MenuRadioCheck{position:absolute;left:1em}.MathJax_MenuRadioCheck.RTL{right:1em;left:auto}.MathJax_MenuLabel{padding:2px 2em 4px 1.33em;font-style:italic}.MathJax_MenuRule{border-top:1px solid #CCC;margin:4px 1px 0}.MathJax_MenuDisabled{color:GrayText}.MathJax_MenuActive{background-color:Highlight;color:HighlightText}.MathJax_Menu_Close{position:absolute;width:31px;height:31px;top:-15px;left:-15px}#MathJax_Zoom{position:absolute;background-color:#F0F0F0;overflow:auto;display:block;z-index:301;padding:.5em;border:1px solid #000;margin:0;font-weight:400;font-style:normal;text-align:left;text-indent:0;text-transform:none;line-height:normal;letter-spacing:normal;word-spacing:normal;word-wrap:normal;white-space:nowrap;float:none;box-shadow:5px 5px 15px #AAA;-webkit-box-shadow:5px 5px 15px #AAA;-moz-box-shadow:5px 5px 15px #AAA;-khtml-box-shadow:5px 5px 15px #AAA;filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}#MathJax_ZoomOverlay{position:absolute;left:0;top:0;z-index:300;display:inline-block;width:100%;height:100%;border:0;padding:0;margin:0;background-color:#fff;opacity:0;filter:alpha(opacity=0)}#MathJax_ZoomFrame{position:relative;display:inline-block;height:0;width:0}#MathJax_ZoomEventTrap{position:absolute;left:0;top:0;z-index:302;display:inline-block;border:0;padding:0;margin:0;background-color:#fff;opacity:0;filter:alpha(opacity=0)}.MathJax_Preview{color:#888}#MathJax_Message{position:fixed;left:1px;bottom:2px;background-color:#E6E6E6;border:1px solid #959595;margin:0;padding:2px 8px;z-index:102;color:#000;font-size:80%;width:auto;white-space:nowrap}#MathJax_MSIE_Frame{position:absolute;top:0;left:0;width:0;z-index:101;border:0;margin:0;padding:0}.MathJax_Error{color:#C00;font-style:italic}footer{position:fixed;font-size:.8em;text-align:right;bottom:0;margin-left:-25px;height:20px;width:100%}
-->

Python socket 粘包的更多相关文章

  1. Python socket粘包解决

    socket粘包: socket 交互send时,连续处理多个send时会出现粘包,soket会把两条send作为一条send强制发送,会粘在一起. send发送会根据recv定义的数值发送一个固定的 ...

  2. Python socket粘包问题(最终解决办法)

    套接字: 就是将传输层以下的协议封装成子接口 对于应用程序来说只需调用套接字的接口,写出的程序自然是遵循tcp或udp协议的 实现第一个功能个:实现:通过客户端向服务端发送命令,调取windows下面 ...

  3. Python socket粘包问题(初级解决办法)

    server端配置: import socket,subprocess,struct from socket import * server=socket(AF_INET,SOCK_STREAM) s ...

  4. python socket粘包及实例

    1.在linux中经常出现粘包的出现(因为两个send近靠着,造成接受到的数据是在一起的.)解决方法: 在服务端两send的中间中再添加一个recv(),客户端添加一个send(),服务端收到信息确认 ...

  5. 百万年薪python之路 -- socket粘包问题解决

    socket粘包问题解决 1. 高大上版解决粘包方式(自定制包头) 整体的流程解释 整个流程的大致解释: 我们可以把报头做成字典,字典里包含将要发送的真实数据的描述信息(大小啊之类的),然后json序 ...

  6. Python之粘包

    Python之粘包 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意注意: res=subprocess.Popen(cmd.deco ...

  7. Python进阶----粘包,解决粘包(旗舰版)

    Python进阶----粘包,解决粘包(旗舰版) 一丶粘包 只有TCP有粘包现象,UDP永远不会粘包 什么是粘包     存在于客户端接收数据时,不能一次性收取全部缓冲区中的数据.当下一次再有数据来时 ...

  8. Socket粘包问题

    这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通 ...

  9. C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)

    介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...

随机推荐

  1. ubuntu18.04安装配置opencv3.4.0

    1.安装配置相关工具及依赖库 sudo apt-get install build-essential # 必须的,gcc编译环境 sudo apt-get install cmake git lib ...

  2. 一些我推荐的和想上的网络课程(Coursera, edX, Udacity)

    从面向找工作的角度出发,我觉得以下课程有很大帮助: 首推Robert Sedgewick,也是我觉得对我帮助最大的老师,讲课特点是能把复杂的算法讲解清楚(典型例子:红黑树,KMP算法) 他在Cours ...

  3. IT兄弟连 Java语法教程 运行Java程序

    编译好Java字节码文件后,接下来就应该运行Java程序了. 运行Java程序需要使用JDK中提供的java命令,因为已经把java命令所在的路径添加到了系统的Path环境变量中,因此现在可以直接使用 ...

  4. 利用正则取出Stirng中“”引号内的内容

    // 取出所有""中间的内容,正则如下 Pattern pattern1 = Pattern.compile("(?<=\")([\\S]+?)(?=\& ...

  5. 关于fiddler抓取HTTPS请求443的问题

    1.环境:fiddler4.IOS10.3以上 2.需求:使用fiddler抓取IOS上的https请求 3.解决方案 步骤一:设置fiddler 步骤二:手机端安装证书 手机设置代理,打开手机浏览器 ...

  6. Python学习笔记(yield与装饰器)

    yeild:返回一个生成器对象: 装饰器:本身是一个函数,函数目的装饰其他函数(调用其他函数) 功能:增强被装饰函数的功能 装饰器一般接受一个函数对象作为参数,以便对其增强 @原函数名  来调用其他函 ...

  7. jsp学习与提高(三)——JSP Cookie 处理

    1.cookie是什么 Cookie是存储在客户机的文本文件,它们保存了大量轨迹信息.在servlet技术基础上,JSP显然能够提供对HTTP cookie的支持. 通常有三个步骤来识别回头客: 服务 ...

  8. java基础第四篇之面向对象

    7.封装与面向对象 a.方法: public static void main(String[] args) { } 一般定义标准: 形参:一般把 不确定的量或者变化的量定义在形参位置//圆的的半径, ...

  9. Python-14-抽象及关键字参数

    可使用内置函数callable判断某个对象是否可调用 >>> import math >>> x = 1 >>> y = math.sqrt &g ...

  10. dp优化1——sgq(单调队列)

    该文是对dp的提高(并非是dp入门,dp入门者请先参考其他文章) 有时候dp的复杂度也有点大...会被卡. 这几次blog大多数会讲dp优化. 回归noip2017PJT4.(题目可以自己去百度).就 ...