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

匿名 (未验证) 提交于 2019-12-02 22:51:30

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!