网络编程 - socket通信/粘包/文件传输/udp - 总结
socket通信 1.简单的套接字通信
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('starting...')
conn,client_addr = phone.accept()
data = conn.recv(1024)
conn.send(data.upper())
conn.close()
phone.close()
服务端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
phone.send('hello'.encode('utf-8'))
data = phone.recv(1024)
print(data)
客户端
2.加上通信循环
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('starting...')
conn,client_addr = phone.accept()
while True:
data = conn.recv(1024)
print('%s 客户端发的数据'%str(client_addr),data)
conn.send(data.upper())
conn.close()
phone.close()
服务端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
while True:
msg = input('msg>>>:').strip()
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print('服务端返回的数据:',data)
phone.close()
客户端
3.bug 修复
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#如果遇到:Address already in use,需要socket配置,重用ip和端口,这里适合windows
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('starting...')
conn,client_addr = phone.accept()
while True:
try: # client断开,这里适合windows
data = conn.recv(1024)
if not data:break # client断开,这里适合linux
print(data)
conn.send(data.upper())
except ConnectionResetError as e:
print(e)
break
conn.close()
phone.close()
服务端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
while True:
msg = input('msg>>>:').strip()
if not msg: continue # 不能发 '' 空 数据 因为数据传给了 os os收到空 不会处理传到server端
phone.send(msg.encode('utf-8')) # 发送数据 将str型转成bytes型
data = phone.recv(1024)
print(data.decode('utf-8')) # 收数据 将bytes型转成str型
phone.close()
客户端
4.加上链接循环
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('starting...')
while True:
conn,client_addr = phone.accept()
while True:
try:
data = conn.recv(1024)
if not data:break
print('%s 的数据'%str(client_addr),data)
conn.send(data.upper())
except ConnectionResetError as e:
# print(e)
break
conn.close()
phone.close()
服务端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
while True:
msg = input("msg>>>:").strip()
if not msg:continue
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data.decode('utf-8'))
phone.close()
客户端
5.模拟ssh远程执行命令
import subprocess
obj = subprocess.Popen('dir d:',shell=True,
stdout=subprocess.PIPE, # 正确的结果
stderr=subprocess.PIPE) # 错误的结果 print('1:',obj.stdout.read().decode('gbk'))
print('2:',obj.stderr.read()) import socket
import subprocess
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('starting...')
while True:
conn,client_addr = phone.accept()
print(client_addr)
while True:
try:
cmd = conn.recv(1024)
if not cmd: break
print(cmd)
obj = subprocess.Popen(cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read() print(len(stdout)+len(stderr)) conn.send(stdout)
conn.send(stderr) # 这样写比两个加起来 效率高 因为底层粘包不会影响 若是加起来就会新开一块内存
except ConnectionResetError as e:
break
conn.close() phone.close()
服务端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
while True:
cmd = input('cmd>>>:').strip()
if not cmd:continue # 一定要写 不允许发空
phone.send(cmd.encode('utf-8'))
data = phone.recv(1024) # 这里如果收到的数据 > 1024 就发生了粘包
print(len(data))
print(data.decode('gbk')) # linux 是gbk windows是utf-8 phone.close()
客户端
粘包 6.粘包
# 数据量比较小 时间比较短 才会发生粘包
# 解决粘包的办法:
# 明确知道对方给我发的包的长度 import socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',8080))
server.listen(5)
conn,client_addr = server.accept()
res1 = conn.recv(3)
print(res1.decode('utf-8'))
res2 = conn.recv(3)
print(res2)
res3 = conn.recv(10)
print(res3) print(len('我们'.encode('utf-8'))) # len() 中文表示的是字符的长度 转成bytes型 len() 表示字节长度
服务端
# send recv 不是一一对应,一发可以多收,一收可以多发
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
client.send('我们'.encode('utf-8'))
client.send(b'hello')
client.send(b'world')
客户端
7.解决粘包 简单版
# struct模块 介绍
import struct
import json
# struct 模块可以将很长的一个数字压缩成4位
# i 有限的 若数字过大,会报错
# q Q d 是8位 i l L 是4位 d 不会报错 res = struct.pack('i',23213123)
print(res,len(res),type(res))
# b'C4b\x01' 4 <class 'bytes'>
data = struct.unpack('i',res)
print(data)
# (23213123,) header_dic = {
'filename': 'a.txt',
'md5': '我们',
'total_size':1231142342342342323423432423234234
}
header_json = json.dumps(header_dic)
print(len(header_json.encode('utf-8')))
header_bytes = header_json.encode('utf-8')
res = struct.pack('i',len(header_bytes))
print(res,len(res))
data = struct.unpack('i',res)
print(data)
struct 模块
import socket
import subprocess
import struct
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',8080))
server.listen(5)
print('starting...')
while True:
conn,client_addr = server.accept()
print(client_addr)
while True:
try:
cmd = conn.recv(1024)
if not cmd:continue
print(cmd)
obj = subprocess.Popen(cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
total_size = len(stdout) + len(stderr) print(total_size)
header = struct.pack('i',total_size)
conn.send(header)
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError as e:
# print(e)
break
conn.close() server.close()
服务端
import socket
import struct
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
cmd = input('>>>:').strip()
if not cmd: continue
client.send(cmd.encode('utf-8'))
obj = client.recv(4)
total_size = struct.unpack('i',obj)[0] # recv_data = client.recv(total_size) # 不能这样做 因为total_size 很可能很大,
# 有关部门建议的不要超过8192,再大反而会出现影响收发速度和不稳定的情况
recv_size = 0
recv_data = b'' # 这里不能写 None
while recv_size < total_size:
res = client.recv(1024)
recv_data += res
recv_size += len(res) print(recv_data.decode('gbk')) # linux 是utf-8 windows 是gbk client.close()
客户端
8.解决粘包 终极版
import socket
import subprocess
import struct
import pickle server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',8080))
server.listen(5)
print('starting...')
while True:
conn,client_addr = server.accept()
print(client_addr)
while True:
try:
cmd = conn.recv(1024)
if not cmd:continue
obj = subprocess.Popen(cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
total_size = len(stdout) + len(stderr) header_dic = {
'filename':'a.txt',
'md5': 'xxxxxx',
'total_size':total_size
}
header_bytes = pickle.dumps(header_dic)
conn.send(struct.pack('i',len(header_bytes)))
conn.send(header_bytes)
conn.send(stdout)
conn.send(stderr) except ConnectionResetError:
break
conn.close() server.close()
服务端
import socket
import struct
import pickle
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
cmd = input('>>>:').strip()
if not cmd: continue
client.send(cmd.encode('utf-8'))
header = client.recv(4)
header_size = struct.unpack('i',header)[0]
header_bytes = client.recv(header_size)
header_dic = pickle.loads(header_bytes)
print(header_dic)
total_size = header_dic['total_size'] recv_size = 0
recv_data = b''
while recv_size < total_size:
res = client.recv(1024)
recv_data += res
recv_size += len(res)
print(recv_data.decode('gbk')) client.close()
客户端
文件传输
9.文件传输 简单版
import socket
import os
import struct
import pickle dirname = os.path.dirname(os.path.abspath(__file__))
filepath = os.path.join(dirname,'share') server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',8080))
server.listen(5)
print('starting...')
while True:
conn,client_addr = server.accept()
print(client_addr)
while True:
try:
res = conn.recv(1024)
if not res:continue
cmds = res.decode('utf-8').split()
filename = cmds[1] file_path = os.path.join(filepath,filename)
if os.path.isfile(file_path):
header = {
'filename': filename,
'md5': 'xxxxxx',
'file_size': os.path.getsize(file_path)
}
header_bytes = pickle.dumps(header)
conn.send(struct.pack('i',len(header_bytes)))
conn.send(header_bytes) with open(file_path,'rb') as f:
for line in f:
conn.send(line)
else:
conn.send(struct.pack('i',0))
except ConnectionResetError:
break
conn.close() server.close()
服务端
import socket
import struct
import pickle
import os dirname = os.path.dirname(os.path.abspath(__file__))
filepath = os.path.join(dirname,'download') client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
msg = input(">>>:").strip() # get a.txt
if not msg:continue
client.send(msg.encode('utf-8'))
obj = client.recv(4)
header_size = struct.unpack('i',obj)[0]
if header_size == 0:
print('文件不存在')
else:
header_types = client.recv(header_size)
header_dic = pickle.loads(header_types)
print(header_dic)
file_size = header_dic['file_size']
filename = header_dic['filename'] with open('%s/%s' % (filepath, filename), 'wb') as f:
recv_size = 0
while recv_size < file_size:
res = client.recv(1024)
f.write(res)
recv_size += len(res)
print('总大小:%s 已下载:%s'%(file_size,recv_size)) client.close()
客户端
10.文件传输 优化版
import socket
import os
import struct
import pickle dirname = os.path.dirname(os.path.abspath(__file__))
filepath = os.path.join(dirname, 'share') def get(cmds,conn):
filename = cmds[1]
file_path = os.path.join(filepath, filename)
if os.path.isfile(file_path):
header = {
'filename': filename,
'md5': 'xxxxxx',
'file_size': os.path.getsize(file_path)
}
header_bytes = pickle.dumps(header)
conn.send(struct.pack('i', len(header_bytes)))
conn.send(header_bytes) with open(file_path, 'rb') as f:
for line in f:
conn.send(line)
else:
conn.send(struct.pack('i', 0)) def put(cmds,conn):
pass def run():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)
print('starting...')
while True:
conn, client_addr = server.accept()
print(client_addr)
while True:
try:
res = conn.recv(1024)
if not res: continue
cmds = res.decode('utf-8').split()
if cmds[0] == 'get':
get(cmds,conn)
elif cmds[0] == 'put':
put(cmds,conn)
except ConnectionResetError:
break
conn.close() server.close() if __name__ == '__main__':
run()
服务端
import socket
import struct
import pickle
import os dirname = os.path.dirname(os.path.abspath(__file__))
filepath = os.path.join(dirname,'download') def get(client):
obj = client.recv(4)
header_size = struct.unpack('i', obj)[0]
if header_size == 0:
print('文件不存在')
else:
header_types = client.recv(header_size)
header_dic = pickle.loads(header_types)
print(header_dic)
file_size = header_dic['file_size']
filename = header_dic['filename'] with open('%s/%s' % (filepath, filename), 'wb') as f:
recv_size = 0
while recv_size < file_size:
res = client.recv(1024)
f.write(res)
recv_size += len(res)
print('总大小:%s 已下载:%s' % (file_size, recv_size)) def put():
pass def run():
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
msg = input(">>>:").strip() # get a.txt
if not msg:continue
client.send(msg.encode('utf-8')) cmds = msg.split()
if cmds[0] == 'get':
get(client)
elif cmds[0] == 'put':
put() client.close() if __name__ == '__main__':
run()
客户端
11.文件传输 面向对象版本
import socket
import os
import struct
import pickle class TCPServer:
address_family = socket.AF_INET
socket_type = socket.SOCK_STREAM
listen_count = 5
max_recv_bytes = 8192
coding = 'utf-8'
allow_reuse_address = False
# 下载的文件存放路径
down_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'share')
# 上传的文件存放路径
upload_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'upload') def __init__(self,server_address,bind_and_listen=True):
self.server_address = server_address
self.socket = socket.socket(self.address_family,self.socket_type) if bind_and_listen:
try:
self.server_bind()
self.server_listen()
except Exception:
self.server_close() def server_bind(self):
if self.allow_reuse_address:
self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self.socket.bind(self.server_address) def server_listen(self):
self.socket.listen(self.listen_count) def server_close(self):
self.socket.close() def server_accept(self):
return self.socket.accept() def conn_close(self,conn):
conn.close() def run(self):
print('starting...')
while True:
self.conn,self.client_addr = self.server_accept()
print(self.client_addr)
while True:
try:
res = self.conn.recv(self.max_recv_bytes)
if not res:continue
cmds = res.decode(self.coding).split()
if hasattr(self,cmds[0]):
func = getattr(self,cmds[0])
func(cmds)
except Exception:
break
self.conn_close(self.conn) def get(self,cmds):
""" 下载
1.找到下载的文件
2.发送 header_size
3.发送 header_bytes file_size
4.读文件 rb 发送 send(line)
5.若文件不存在,发送0 client提示:文件不存在
:param cmds: 下载的文件 eg:['get','a.txt']
:return:
"""
filename = cmds[1]
file_path = os.path.join(self.down_filepath, filename)
if os.path.isfile(file_path):
header = {
'filename': filename,
'md5': 'xxxxxx',
'file_size': os.path.getsize(file_path)
}
header_bytes = pickle.dumps(header)
self.conn.send(struct.pack('i', len(header_bytes)))
self.conn.send(header_bytes)
with open(file_path, 'rb') as f:
for line in f:
self.conn.send(line)
else:
self.conn.send(struct.pack('i', 0)) def put(self,cmds):
""" 上传
1.接收4个bytes 得到文件的 header_size
2.根据 header_size 得到 header_bytes header_dic
3.根据 header_dic 得到 file_size
3.以写的形式 打开文件 f.write()
:param cmds: 下载的文件 eg:['put','a.txt']
:return:
"""
obj = self.conn.recv(4)
header_size = struct.unpack('i', obj)[0]
header_bytes = self.conn.recv(header_size)
header_dic = pickle.loads(header_bytes)
print(header_dic)
file_size = header_dic['file_size']
filename = header_dic['filename'] with open('%s/%s' % (self.upload_filepath, filename), 'wb') as f:
recv_size = 0
while recv_size < file_size:
res = self.conn.recv(self.max_recv_bytes)
f.write(res)
recv_size += len(res) tcp_server = TCPServer(('127.0.0.1',8080))
tcp_server.run()
tcp_server.server_close()
服务端
import socket
import struct
import pickle
import os class FTPClient:
address_family = socket.AF_INET
socket_type = socket.SOCK_STREAM
# 下载的文件存放路径
down_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'download')
# 上传的文件存放路径
upload_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'share')
coding = 'utf-8'
max_recv_bytes = 8192 def __init__(self, server_address, connect=True):
self.server_address = server_address
self.socket = socket.socket(self.address_family, self.socket_type)
if connect:
try:
self.client_connect()
except Exception:
self.client_close() def client_connect(self):
self.socket.connect(self.server_address) def client_close(self):
self.socket.close() def run(self):
while True:
# get a.txt 下载 put a.txt 上传
msg = input(">>>:").strip()
if not msg: continue
self.socket.send(msg.encode(self.coding))
cmds = msg.split()
if hasattr(self,cmds[0]):
func = getattr(self,cmds[0])
func(cmds) def get(self, cmds):
""" 下载
1.得到 header_size
2.得到 header_types header_dic
3.得到 file_size file_name
4.以写的形式 打开文件
:param cmds: 下载的内容 eg: cmds = ['get','a.txt']
:return:
"""
obj = self.socket.recv(4)
header_size = struct.unpack('i', obj)[0]
if header_size == 0:
print('文件不存在')
else:
header_types = self.socket.recv(header_size)
header_dic = pickle.loads(header_types)
print(header_dic)
file_size = header_dic['file_size']
filename = header_dic['filename'] with open('%s/%s' % (self.down_filepath, filename), 'wb') as f:
recv_size = 0
while recv_size < file_size:
res = self.socket.recv(self.max_recv_bytes)
f.write(res)
recv_size += len(res)
print('总大小:%s 已下载:%s' % (file_size, recv_size))
else:
print('下载成功!') def put(self, cmds):
""" 上传
1.查看上传的文件是否存在
2.上传文件 header_size
3.上传文件 header_bytes
4.以读的形式 打开文件 send(line)
:param cmds: 上传的内容 eg: cmds = ['put','a.txt']
:return:
"""
filename = cmds[1]
file_path = os.path.join(self.upload_filepath, filename)
if os.path.isfile(file_path):
file_size = os.path.getsize(file_path)
header = {
'filename': os.path.basename(filename),
'md5': 'xxxxxx',
'file_size': file_size
}
header_bytes = pickle.dumps(header)
self.socket.send(struct.pack('i', len(header_bytes)))
self.socket.send(header_bytes) with open(file_path, 'rb') as f:
send_bytes = b''
for line in f:
self.socket.send(line)
send_bytes += line
print('总大小:%s 已上传:%s' % (file_size, len(send_bytes)))
else:
print('上传成功!')
else:
print('文件不存在') ftp_client = FTPClient(('127.0.0.1',8080))
ftp_client.run()
ftp_client.client_close()
客户端
UDP
12.UDP协议 简单版
import socket
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8080))
while True:
data,client_addr = server.recvfrom(1024)
print('客户端数据:',data)
server.sendto(data.upper(),client_addr)
服务端
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
msg = input('>>>:').strip()
client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
data,server_addr =client.recvfrom(10224)
print(data,server_addr)
客户端
13.UDP协议 不会粘包
import socket
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8080))
res1 = server.recvfrom(5)
print(res1)
res2 = server.recvfrom(1024)
print(res2)
server.close()
服务端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
client.sendto(b'hello',('127.0.0.1',8080))
client.sendto(b'world',('127.0.0.1',8080))
client.close()
客户端
14.UDP 执行指令查看服务端的时间,设置时间同步
import socket
import subprocess
import time
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8080))
while True:
data,client_addr = server.recvfrom(1024)
print(data,client_addr)
# obj = subprocess.Popen(data.decode('utf-8'),shell=True, # time 命令在windows 下不能用
# stdout=subprocess.PIPE,
# stderr=subprocess.PIPE)
# stdout = obj.stdout.read()
# stderr = obj.stderr.read()
# print(stdout+stderr)
# server.sendto(stdout+stderr,client_addr)
if data.decode('utf-8') == 'time':
str_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
# str_time = '2017-01-01 00:00:00'
server.sendto(str_time.encode('gbk'),client_addr) server.close()
服务端
import socket
import os
import time
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
msg = input('>>>:').strip()
client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
data,server_addr = client.recvfrom(1024)
print(data.decode('utf-8'),server_addr)
# localtime = time.localtime()
# os.system("date %d-%d-%d" % (localtime.tm_year, localtime.tm_mon, localtime.tm_mday)) # 设置日期
# os.system("time %d:%d:%d.0" % (localtime.tm_hour, localtime.tm_min, localtime.tm_sec)) # 设置时间 client.close()
客户端
网络编程 - socket通信/粘包/文件传输/udp - 总结的更多相关文章
- UNIX网络编程——Socket/TCP粘包、多包和少包, 断包
为什么TCP 会粘包 前几天,调试mina的TCP通信, 第一个协议包解析正常,第二个数据包不完整.为什么会这样吗,我们用mina这样通信框架,还会出现这种问题? TCP(transport cont ...
- 网络编程基础之粘包现象与UDP协议
一.粘包现象原理分析 1.我们先来看几行代码,从现象来分析: 测试程序分为两部分,分别是服务端和客户端 服务端.py #!/usr/bin/env python3 #-*- coding:utf-8 ...
- python网络编程-socket上传下载文件(包括md5验证,大数据发送,粘包处理)
ftp server 1) 读取文件名 2)检查文件是否存在 3)打开文件 4)检查文件大小 5)发送文件大小给客户端 6)等客户端确认 7)开始边读边(md5计算)发数据 8)给客户端发md5 ft ...
- (网络编程)基于tcp(粘包问题) udp协议的套接字通信
import socket 1.通信套接字(1人1句)服务端和1个客户端 2.通信循环(1人多句)服务端和1个客户端 3.通信循环(多人(串行)多句)多个客户端(服务端服务死:1个客户端---&g ...
- UNIX网络编程——Socket通信原理和实践
我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠so ...
- java网络编程Socket通信详解
Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而在网络编程中,使用最多的就是Socket.像大家熟悉的QQ.MSN都使用了Socket相关的技术. ...
- 网络编程基础:粘包现象、基于UDP协议的套接字
粘包现象: 如上篇博客中最后的示例,客户端有个 phone.recv(2014) , 当服务端发送给客户端的数据大于1024个字节时, 多于1024的数据就会残留在管道中,下次客户端再给服务端发命令时 ...
- python 网络编程 缓冲和粘包
tcp:属于长连接,与一个客户端进行连接了以后,其他的客户端要等待,要连接另外一个,必须优雅的断开前面这个客户端的连接. 允许地址重用:在bind IP地址和端口之前加上,# server.setso ...
- 网络 --- 3 socket模块 粘包
一 .socket 模块参数及方法 二.缓冲区 三.粘包 1.两种粘包现象 ①连续的小包可能会被优化算法给组合到一起进行发送 ②第一次如果发送的数据大小2000B接收端一次性接受大小为1024, 这就 ...
随机推荐
- 如何重设 MySQL 的 root 密码
MySQL下创建新用户.新数据库.设定访问权限控制都需要用到root密码.万一把root密码忘了,该怎么办? 幸运地是,重设密码很容易. 安全模式重置法 基本的思路是,以安全模式启动mysql,这样不 ...
- 对java中arraylist深入理解
1.ArrayList插入删除一定慢么? 取决于你删除的元素离数组末端有多远,ArrayList拿来作为堆栈来用还是挺合适的,push和pop操作完全不涉及数据移动操作. 2.ArrayList的遍历 ...
- Netty4.x中文教程系列(七)UDP协议
将近快一年时间没有更新Netty的博客.一方面原因是因为项目进度的问题.另外一方面是博主有一段时间去熟悉Unity3D引擎. 本章节主要记录博主自己Netty的UDP协议使用. 1. 构建UDP服务端 ...
- /proc/meminfo分析
参考: 1. linux/Documentation/filesystems/proc.txt 2. Linux 中 /proc/meminfo 的含义 3. redhat deployment gu ...
- asp.net 后台调用confirm
using System;using System.Web.UI; public partial class _Default : System.Web.UI.Page, IPostBackEvent ...
- Cocos2d-X中的Slider控件
Slider控件事实上就是滑块控件.经常使用于音乐中的音量控制,在Windows编程中开发音乐播放器就须要用到滑块控件控制音量 首先在project文件夹下的Resource文件夹中放 在Skider ...
- ES插件elasticsearch-mapper-attachments 2.3.4及各个版本正确下载地址
ES版本更新那么快,文档链接你也倒是跟上啊, 插件zip包下载,都是error link...难不成是我网络原因? 下载zip页面报错信息: This XML file does not appear ...
- Oracle Data Provider for .NET的使用(三)-ORACLE与.NET类型对应关系
想来这个是最重要的事情了,因为多数情况下,我们使用dbhelper来调用数据库的时候,是因为如下三个地方导致错误: 1.错误的sql语句:末尾多了分号,少了部分关键字 2.sql中的参数与parame ...
- VC++ GetSafeHwnd用法
GetSafeHwnd HWND GetSafeHwnd() const; 当我们想得到一个窗口对象(CWnd的派生对象)指针的句柄(HWND)时,最安全的方法是使用GetSafeHwnd()函数. ...
- 判断ActiveX控件是Desgin Mode还是Runtime Mode
对于MFC COleControl::AmbientUserMode Determines if the Container is in design mode or user mode. BOOL ...