Erlo

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

2019-06-18 23:02:15 发布   211 浏览  
页面报错/反馈
收藏 点赞

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()
    服务端
  3.     

     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()
    客户端

     

登录查看全部

参与评论

评论留言

还没有评论留言,赶紧来抢楼吧~~

手机查看

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认