socket,socketserver,tcp黏包问题,网络编程

2023-11-22 05:10

本文主要是介绍socket,socketserver,tcp黏包问题,网络编程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1,socket的使用

  1. 基于TCP的socket的使用
    TCP是有链接,面向流的,客户端和服务端一旦连接,不在断开的时候是不会断的
    简单使用
     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     3 # @time     : 2019/6/13 19:36
     4 # @Author   : aolishuai
     5 # @File     : 服务端
     6 
     7 import socket
     8 
     9 #创建一个socket对象
    10 server = socket.socket()#创建一个手机
    11 
    12 ip_port = ('192.168.1.9',8001)#创建一张电话卡
    13 
    14 server.bind(ip_port)#插上电话卡
    15 
    16 #监听IP地址和端口
    17 server.listen()#开机,listen(10)后面可以有10人等待,超过10人,直接让超过的人数去掉
    18 
    19 
    20 print(1111)
    21 #等待客户端的连接
    22 conn, addr =server.accept()
    23 #接收消息
    24 from_client_msg=conn.recv(1024)#单位大小为B,1KB=1024B
    25 #消息字符转换并打印
    26 print(from_client_msg.decode('utf-8'))
    27 #消息发给客户端
    28 conn.send("勇士说的".encode('utf-8'))
    29 
    30 #消息发完断开连接,
    31 conn.close()
    32 #服务端关机
    33 server.close()
    服务端
     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     3 # @time     : 2019/6/13 19:36
     4 # @Author   : aolishuai
     5 # @File     : 客户端
     6 import socket
     7 client = socket.socket()
     8 #拿到服务端IP和端口
     9 server_ip_port = ('192.168.1.9',8001)
    10 #连接服务端
    11 client.connect(server_ip_port)
    12 #发消息
    13 client.send("kd断了".encode('utf-8'))
    14 
    15 from_server_msg=client.recv(1024)
    16 from_server_msg=from_server_msg.decode("utf-8")
    17 print(from_server_msg)
    18 
    19 #客户端关闭
    20 client.close()
    客户端

     

  2. UDP是没有连接,服务端只能在接收客户端发过来的消息获取到客户端的地址之后,才能返回消息
     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     3 # @time     : 2019/6/14 15:51
     4 # @Author   : aolishuai
     5 # @File     : server
     6 
     7 import socket
     8 
     9 sk = socket.socket(type=socket.SOCK_DGRAM)
    10 sk.bind(('127.0.0.1',8081))
    11 
    12 msg,addr = sk.recvfrom(1024)
    13 print(msg.decode('utf-8'))
    14 sk.sendto(b'hihao',addr)
    15 
    16 sk.close()
    服务端
     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     3 # @time     : 2019/6/14 15:51
     4 # @Author   : aolishuai
     5 # @File     : client
     6 import socket
     7 sk = socket.socket(type=socket.SOCK_DGRAM)
     8 ip_port=('127.0.0.1',8081)
     9 
    10 sk.sendto(b'hi',ip_port)
    11 msg,addr=sk.recvfrom(1024)
    12 print(msg.decode('utf-8'))
    13 sk.close()
    客户端

    简单的UDPsock使用,服务端是一个时间服务器,在客户端需要发送的时候,发送对应格式的时间

     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     3 # @time     : 2019/6/14 16:18
     4 # @Author   : aolishuai
     5 # @File     : time_server
     6 import socket,time
     7 
     8 sk = socket.socket(type=socket.SOCK_DGRAM)
     9 ip_port=('127.0.0.1',8082)
    10 
    11 sk.bind(ip_port)
    12 
    13 while True:
    14     msg,addr = sk.recvfrom(1024)
    15     msg=msg.decode('utf-8')
    16     print(msg)
    17     t =time.localtime(time.time())
    18     give_t = time.strftime(msg,t)
    19     sk.sendto(give_t.encode('utf-8'),addr)
    20 
    21 sk.close()
    服务端

    

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @time     : 2019/6/14 16:18
 4 # @Author   : aolishuai
 5 # @File     : time_client
 6 
 7 import socket
 8 
 9 sk = socket.socket(type=socket.SOCK_DGRAM)
10 ip_port=('127.0.0.1',8082)
11 while True:
12     geshi = input('请输入时间格式:').encode('utf-8')
13     sk.sendto(geshi,ip_port)
14     msg,addr = sk.recvfrom(1024)
15     msg= msg.decode('utf-8')
16     print('时间是{0}'.format(msg))
17 sk.close()
客户端

 

    1. 黏包问题
      黏包问题:
      tcp协议在进行socket传输的时候,
      1,不知道包有多大,接收的时候可能分多次接收
      2,连续传递小数据包,自身优化时间算法,将多个小包一块发送
      这两种情况会导致黏包


      解决黏包问题
      1,传输的时候,先传递包大小,根据大小,确定接收值,返回收到后,再进行传输
      2,使用struct模块,传输的时候先将包大小传过去,在直接传输数据包


      1,不使用struct模块解决黏包问题,需要在发送你要发的数据之前,先计算数据大小,先告诉服务端要发的数据大小,然后服务端通过接受到数据大小来确定接收数值
       1 #!/usr/bin/env python
       2 # -*- coding: utf-8 -*-
       3 # @time     : 2019/6/14 22:40
       4 # @Author   : aolishuai
       5 # @File     : server
       6 import socket
       7 
       8 sk = socket.socket()
       9 ip_port = ('127.0.0.1', 8010)
      10 sk.bind(ip_port)
      11 sk.listen()
      12 conn, addr = sk.accept()
      13 
      14 while True:
      15     cmd = input('请输入命令:').encode('gbk')
      16     conn.send(cmd)
      17     ret = conn.recv(1024).decode('utf-8')
      18     conn.send(b'ok')
      19     ret2 = conn.recv(int(ret)).decode('gbk')
      20     print(ret2)
      21 
      22 
      23 conn.close()
      24 sk.close()
      服务端

       

       1 #!/usr/bin/env python
       2 # -*- coding: utf-8 -*-
       3 # @time     : 2019/6/14 22:40
       4 # @Author   : aolishuai
       5 # @File     : client
       6 import socket,subprocess
       7 
       8 sk = socket.socket()
       9 ip_port = ('127.0.0.1',8010)
      10 sk.connect(ip_port)
      11 
      12 while True:
      13     msg = sk.recv(1024).decode('gbk')
      14     ret = subprocess.Popen(msg,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
      15     std_out = ret.stdout.read()
      16     std_err = ret.stderr.read()
      17     num = str(len(std_out)+len(std_err)).encode('utf-8')
      18     sk.send(num)
      19     sk.recv(1024)
      20     sk.send(std_out)
      21     sk.send(std_err)
      22 sk.close()
      客户端

       

    2.  

      使用struct模块解决黏包问题,struct能把一个类型的数据,转换成相应的bytes类

       1 #!/usr/bin/env python
       2 # -*- coding: utf-8 -*-
       3 # @time     : 2019/6/15 10:56
       4 # @Author   : aolishuai
       5 # @File     : server
       6 
       7 import socket,struct
       8 
       9 sk = socket.socket()
      10 ip_port = ('127.0.0.1', 8010)
      11 sk.bind(ip_port)
      12 sk.listen()
      13 conn, addr = sk.accept()
      14 
      15 while True:
      16     cmd = input('请输入命令:').encode('gbk')
      17     conn.send(cmd)
      18     #ret = conn.recv(1024).decode('utf-8')
      19     ret = conn.recv(4)
      20     ret = struct.unpack('i',ret)[0]
      21 
      22 
      23     #conn.send(b'ok')
      24     ret2 = conn.recv(ret).decode('gbk')
      25     print(ret2)
      26 
      27 
      28 conn.close()
      29 sk.close()
      服务端
       1 #!/usr/bin/env python
       2 # -*- coding: utf-8 -*-
       3 # @time     : 2019/6/15 10:56
       4 # @Author   : aolishuai
       5 # @File     : client
       6 import socket,subprocess,struct
       7 
       8 sk = socket.socket()
       9 ip_port = ('127.0.0.1',8010)
      10 sk.connect(ip_port)
      11 
      12 while True:
      13     msg = sk.recv(1024).decode('gbk')
      14     ret = subprocess.Popen(msg,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
      15     std_out = ret.stdout.read()
      16     std_err = ret.stderr.read()
      17     #num = str(len(std_out)+len(std_err)).encode('utf-8')
      18     num  = len(std_out)+len(std_err)
      19     num = struct.pack('i',num)
      20     sk.send(num)
      21     #sk.recv(1024)
      22     sk.send(std_out)
      23     sk.send(std_err)
      24 sk.close()
      客户端

       


       

2,socketserver

使用tcp时,server端和client端只能链一个,通过socketserver能够使多个client与server同时连接

启用的时候,只有server端需要继承socketserver服务

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @time     : 2019/6/16 13:25
 4 # @Author   : aolishuai
 5 # @File     : socketserver
 6 
 7 import socketserver
 8 #必须创建一个类
 9 class MyServer(socketserver.BaseRequestHandler):
10     def handle(self):
11         while True:
12             msg = self.request.recv(1024).decode('utf-8')
13             print(msg)
14             info = input('>>>')
15             self.request.send(info.encode('utf-8'))
16 
17 
18         #print(self.request.recv(1024))#self.request==conn
19 
20 
21 if __name__ == '__main__':
22     server = socketserver.ThreadingTCPServer(('127.0.0.1',8090),MyServer)
23     server.serve_forever()
服务端
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @time     : 2019/6/16 13:33
 4 # @Author   : aolishuai
 5 # @File     : client
 6 import socket
 7 sk = socket.socket()
 8 sk.connect('127.0.0.1',8090)
 9 while True:
10     msg = input('>>>>>')
11     sk.send(msg.encode('utf-8'))
12     ret = sk.recv(1024).decode('utf-8')
13     print(ret)
14 sk.close()
客户端

 

转载于:https://www.cnblogs.com/shuai-aoli/p/11048076.html

这篇关于socket,socketserver,tcp黏包问题,网络编程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/407750

相关文章

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja

MySQL 表空却 ibd 文件过大的问题及解决方法

《MySQL表空却ibd文件过大的问题及解决方法》本文给大家介绍MySQL表空却ibd文件过大的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录一、问题背景:表空却 “吃满” 磁盘的怪事二、问题复现:一步步编程还原异常场景1. 准备测试源表与数据

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

SysMain服务可以关吗? 解决SysMain服务导致的高CPU使用率问题

《SysMain服务可以关吗?解决SysMain服务导致的高CPU使用率问题》SysMain服务是超级预读取,该服务会记录您打开应用程序的模式,并预先将它们加载到内存中以节省时间,但它可能占用大量... 在使用电脑的过程中,CPU使用率居高不下是许多用户都遇到过的问题,其中名为SysMain的服务往往是罪魁

AOP编程的基本概念与idea编辑器的配合体验过程

《AOP编程的基本概念与idea编辑器的配合体验过程》文章简要介绍了AOP基础概念,包括Before/Around通知、PointCut切入点、Advice通知体、JoinPoint连接点等,说明它们... 目录BeforeAroundAdvise — 通知PointCut — 切入点Acpect — 切面