目录

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. [openjudge] 2797最短前缀 Trie

    描述 一个字符串的前缀是从该字符串的第一个字符起始的一个子串.例如 "carbon"的字串是: "c", "ca", "car&q ...

  2. centos7及以上安装git服务

    检查git是否安装或者是版本 whereis git等命令来检查是否已经安装了git版本的 git --version检测到我的环境自带的git版本 已安装但不是想要的版本需要卸载 yum remov ...

  3. 51nod1112(xjb)

    題目鏈接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1112 題意:中文題誒- 思路:對於函數 f(x) = a + ...

  4. SpringMVC入门 bug集锦X3和SSM原始整合

  5. [Java]三大特性之封装

    封装这个我们可以从字面上来理解,简单来说就是包装的意思,专业点就是信息隐藏. 是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可 ...

  6. Codeforces 1167F(计算贡献)

    要点 容易想到排序,然后对于每个数: 人的惯性思维做法是:\(a[i]*(rank1的+rank2的+-)\).然而解法巧妙之处在于直接把所有的加和当成一个系数,然后先假装所有情况系数都是1,接着往上 ...

  7. Codeforces Round #431 (Div. 2) A

    Where do odds begin, and where do they end? Where does hope emerge, and will they ever break? Given ...

  8. NET Everywhere

    NET Everywhere 8月份已经发布了.NET Core 2.0, 大会Keynote 一开始花了大量的篇幅回顾.NET Core 2.0的发布,社区的参与度已经非常高.大会的主题是.NET ...

  9. Net Core2.0下使用Dapper

    Net Core2.0下使用Dapper 今天成功把.Net Framework下使用Dapper进行封装的ORM成功迁移到.Net Core 2.0上,在迁移的过程中也遇到一些很有意思的问题,值得和 ...

  10. asp.net 多语言 在IIS7.5发布出现找不到资源文件

    我也遇到这个问题,纠结了半天, 最后把资源文件的属性改为:内容 就可以了. 见:http://q.cnblogs.com/q/60443/