1. TCP协议下的如何解决粘包问题

  TCP(transport control protocol 传输控制协议)  使用Nagle算法,将多次间隔较小且数据量小的数据,合并成大的数据块;接受端无法识别每条数据的边界,因此产生粘包现象。

"""
Server
"""
from socket import * back_log = 5
bufsize = 1024
ip_port = ('127.0.0.1', 8080) tcp_server = socket(AF_INET, SOCK_STREAM) # 数据流
tcp_server.bind(ip_port)
tcp_server.listen(back_log) while True:
print('服务端开始处理连接。。。')
conn, addr = tcp_server.accept()
print('客户端连接', conn)
print('客户端地址', addr)
while True:
try:
data = conn.recv(bufsize)
if not data:
break
print('接收到的数据', data)
conn.send(data.upper())
except Exception as e:
print(e)
break
"""
Client
"""
from socket import * bufsize = 1024
ip_port = ('127.0.0.1', 8080) tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port)
tcp_client.send('hello'.encode('utf-8'))
tcp_client.send('world'.encode('utf-8'))
response = tcp_client.recv(bufsize)
print('response is ==> ', response) # response is ==> b'HELLOWORLD'

解决思路:告知接收端数据长度,导入struct模块,将字节长度封装成4个字节发送给接收方;

服务端 =====》TCP实现远程操作命令

from socket import *
import subprocess,struct bufsize = 1024
back_log = 5
ip_port = ('127.0.0.1', 8080) tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while True:
conn, addr = tcp_server.accept()
print('current connection', conn)
while True:
try:
cmd = conn.recv(bufsize)
if not cmd:
break
print('data from client', cmd) res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
cmd_res = res.stderr.read()
if not cmd_res:
cmd_res = res.stdout.read()
print('response is:', cmd_res) data_length = struct.pack('i', len(cmd_res))
conn.send(data_length)
conn.send(cmd_res)
except Exception as e:
print(e)
break
# conn.close()

客户端 ====》

from socket import *
import struct bufsize = 100
ip_port = ('127.0.0.1', 8080)
tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port) while True:
cmd = input('>>>> ').strip()
if not cmd:
continue
if cmd == 'quit':
break
tcp_client.send(cmd.encode('utf-8')) length_data = tcp_client.recv(4) length = struct.unpack('i', length_data)[0]
print(length)
response = b''
recsize = 0
while recsize < length:
response += tcp_client.recv(bufsize)
recsize = len(response)
# print('execute result is:', response) # 接受字节长度小于发送数据长度,产生粘包
print('execute result is:', response.decode('gbk'))
tcp_client.close()

2. TCP协议如何实现多个客户端连接(并发处理)

导入socketserver模块,实现ocketserver.BaseRequestHandler,重写 handle 方法

使用

ThreadingTCPServer,线程实现并发
import socketserver

class MyServer(socketserver.BaseRequestHandler):
def handle(self):
print('conn is', self.request) # conn
print('addr is', self.client_address) # addr while True:
try:
data = self.request.recv(1024)
if not data:
break
self.request.sendall(data.upper())
except Exception as e:
print(e)
break if __name__ == '__main__':
ip_port = ('127.0.0.1', 8080)
s = socketserver.ThreadingTCPServer(ip_port, MyServer)
s.serve_forever()


3. 基于UDP套接字

  UDP 与TCP 不同,使用socket时用的时 SOCK_DGRAM 数据报

  sendto()发送的是元组数据类型,包含数据以及连接

  recvfrom()接收的也是数据以及连接

服务端 ====》

from socket import *

ip_port = ('127.0.0.1', 8080)
buf_size = 1024 udp_server = socket(AF_INET, SOCK_DGRAM) # datagram 数据报
udp_server.bind(ip_port) while True:
data, addr = udp_server.recvfrom(buf_size)
print(data)
udp_server.sendto(data.upper(), addr)

客户端====》

from socket import *

ip_port = ('127.0.0.1', 8080)
buf_size = 1024 udp_client = socket(AF_INET, SOCK_DGRAM) # datagram 数据报 while True:
msg = input('==>: ').strip()
udp_client.sendto(msg.encode('utf-8'), ip_port)
response, addr = udp_client.recvfrom(buf_size)
print(response.decode('utf-8'))

Python中Socket编程(TCP、UDP)的更多相关文章

  1. python中socket编程

    一.网络协议 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构(互联网中处处是C/S架构):B/S架构也是C/S架构的一种,B/S是浏览器/服务器 C/S架构与socket的关系: ...

  2. 3、linux下Socket编程-TCP/UDP

    1.什么是Socket 网络的 Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符.Socket也具有一个类似于打开文件的函数调用Socket(),该函数返 回一个整型的Socke ...

  3. python day31--网络编程,tcp,udp的指令,及黏包

    一.TCP tcp中遇到黏包会让数据传输完. server import socket sk=socket.socket() sk.bind(('127.0.0.1',8090)) sk.listen ...

  4. Python中Socket编程server与client简单的合法性认证

    导入python自带的hmac模块对随机生成的位数32字节和自定义token进行加密处理 import osmsg = os.urandom(32)  #随机生成msgOut[4]: b"F ...

  5. python之socket编程(一)

    socket之前我们先来熟悉回忆几个知识点. OSI七层模型 OSI(Open System Interconnection)参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标 ...

  6. 网络编程—网络基础概览、socket,TCP/UDP协议

    网络基础概览 socket概览 socket模块—TCP/UDP的实现 TCP/UDP总结 网络基础概览 osi七层协议各层主要的协议 # 物理层传输电信号1010101010 # 数据链路层,以太网 ...

  7. Fixed-Length Frames 谈谈网络编程中应用层(基于TCP/UDP)的协议设计

    http://blog.sina.com.cn/s/blog_48d4cf2d0101859x.html 谈谈网络编程中应用层(基于TCP/UDP)的协议设计 (2013-04-27 19:11:00 ...

  8. 转:Python 的 Socket 编程教程

    这是用来快速学习 Python Socket 套接字编程的指南和教程.Python 的 Socket 编程跟 C 语言很像. Python 官方关于 Socket 的函数请看 http://docs. ...

  9. 操作系统底层原理与Python中socket解读

    目录 操作系统底层原理 网络通信原理 网络基础架构 局域网与交换机/网络常见术语 OSI七层协议 TCP/IP五层模型讲解 Python中Socket模块解读 TCP协议和UDP协议 操作系统底层原理 ...

随机推荐

  1. python 序列与字典

    序列概念: 序列的成员有序排列,可以通过下标访问到一个或几个元素,就类似与c语言的数组. 序列的通用的操作: 1:索引 11 = [1,2,3,4] 11[0] = 1 2:切片 11[1,2,3,4 ...

  2. sqli-labs系列——第三关

    less3 判断注入类型 这第三关有点意思,是一个带括号的数字型注入,这里需要闭合它的括号,之前遇到过很多这样的站,它的sql语句一般都是这样的: $sql = select * from user ...

  3. 从源码剖析Go语言基于信号抢占式调度

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/485 本文使用的go的源码15.7 这一次来讲讲基于信号式抢占式调度 ...

  4. java例题_42 求满足809*??=800*??+9*??+1的??的值

    1 /*42 [程序 42 求数字] 2 题目:809*??=800*??+9*??+1 3 其中??代表的两位数,8*??的结果为两位数,9*??的结果为 3 位数.求??代表的两位数,及 809* ...

  5. 力扣 - 347. 前 K 个高频元素

    目录 题目 思路1(哈希表与排序) 代码 复杂度分析 思路2(建堆) 代码 复杂度分析 题目 347. 前 K 个高频元素 思路1(哈希表与排序) 先用哈希表记录所有的值出现的次数 然后将按照出现的次 ...

  6. Kubernetes 部署策略详解-转载学习

    Kubernetes 部署策略详解 参考:https://www.qikqiak.com/post/k8s-deployment-strategies/ 在Kubernetes中有几种不同的方式发布应 ...

  7. ATMS中去pause Activity A.

    上文写完之后,感觉这个部分写的还是不清晰,本文继续补充一下. 首先还是看堆栈. obtain:78, PauseActivityItem (android.app.servertransaction) ...

  8. [Fundamental of Power Electronics]-PART II-8. 变换器传递函数-8.2 变换器传递函数分析

    8.2 变换器传递函数分析 接下来,让我们推导基本变换器传递函数中的极点,零点和渐近线增益的解析表达式. 8.2.1 示例:Buck-boost变换器的传递函数 Buck-boost变换器的小信号等效 ...

  9. mysql大于当前时间置顶并按升序排序,小于当前时间的置尾并按降序排序

    现在用id来代替时间这样好测试 看一下测试表数据 执行按需求规则排序的sql SELECT * FROM number_generator ORDER BY id < 16 , IF(id &l ...

  10. Java执行groovy脚本的两种方式

    记录Java执行groovy脚本的两种方式,简单粗暴: 一种是通过脚本引擎ScriptEngine提供的eval(String)方法执行脚本内容:一种是执行groovy脚本: 二者都通过Invocab ...