数据结构学习笔记

   本次学习我们学习了TCP/IP的数据结构,并且根据发送的数据,对数据进行切片处理,反馈回来规定的数据。

代码:

(1)服务器端代码:

#coding:utf-8
'''
Created on 2018年9月25日

@author: zerg
'''
from socketserver import ThreadingTCPServer, StreamRequestHandler
import time
import threading

class TcpSer(ThreadingTCPServer):
    def __init__(self,server_address, RequestHandler):
        self.daemon_threads = True
        self.allow_reuse_address = True
        ThreadingTCPServer.__init__(self, server_address, RequestHandler)

        
class RequestHandler(StreamRequestHandler):

    wfiles = []
    rfiles = []
    def handle(self):       
        flag = True
        while flag:
            time.sleep(0.5)
            clientaddress = self.client_address

            if self.wfile not in self.wfiles:
                self.wfiles.append(self.wfile)
                print(str(clientaddress)+"已连接")
                self.wfile.write(b'hello')
            self.getData()
    
#     服务器可以接收如下命令:help,connect,exit
#     服务器端收到help,返回“commands include help,connect,exit” 
#     收到,connect,返回“connect code is 400”
#     收到,exit,返回“exit code is {500}” 
# 数据解析           
    def getData(self):
        while True:
            time.sleep(0.5)
            input = self.rfile.readline(1024)
            input = input.decode().strip()
            print(input)
            if input == 'help':
                self.wfile.write(b'commands include help,connect,exit')
            if input == 'connect':
                self.wfile.write(b'connect code is 400')
            if input == 'exit':
                self.wfile.write(b'exit code is {500}')
            if input not in ['help','connect','exit']:
                self.wfile.write(b'the command is wrong')
        
            


if __name__ == '__main__':
    
    server_address = ('',10001)   
    tcp = TcpSer(server_address,RequestHandler)
    print("服务已开启\r\n")
    tcp.serve_forever()

(2)客户端:

#codiing:utf-8
'''

@author: 15006
'''

import socket
import threading


hostname="localhost"
port=10001
tcpclient = socket.socket()
tcpclient.connect((hostname,port))


def CmdInterface():
    while True:
        sendCmd = input("please input the cmd:\r\n")
        tcpclient.send((sendCmd+'\r\n').encode())
 
 
cmdthread = threading.Thread(target=CmdInterface)
cmdthread.start()


def getLastData(data):
    return data[len(data)-1]

def getHelpData(data):
    return getLastData(data).decode().split(',')

def getConnectData(data):
    return getLastData(data).decode().split(' ')

def getExitData(data):
    rdata=getLastData(data).decode().split("{")
    return getLastData(rdata).split("}")

while True:
    recvData = tcpclient.recv(1024)
    recvData = recvData.split()
    data=getLastData(recvData).decode()
    if (len(recvData)>3):
        if (data == "{500}"):
            data=getExitData(recvData)
            print(data[0])

        else:
            data=getConnectData(recvData)
            print(data)     

       
    elif (len(recvData)==3):
        data=getHelpData(recvData)
        print(data)
    else:
        print(recvData)
        
        
if __name__ == '__main__':
    CmdInterface()
    getLastData()
    getHelpData()
    getConnectData()
    getExitData()

 

最后结果:

学习过程中的收获:

1.服务器端使用wfile进行写文件,如果客户端输入help,就反馈commands include help,connect,exit;如果客户端输入connect,就反馈connect code is 400;如果客户端输入exit,就反馈exit code is {500};如果输入其他信息,就反馈the command is wrong。

2.当接收到的数据中含有空格、回车符、换行符时,使用Strip()方法去掉。

3.使用input()方法发送数据,尤其要注意这里要添加上回车换行符\r\n

4.数据通信时候的编码和解码:在实现tcp/ip通信过程,数据的发送和接收都是通过字节的形式,结合OSI七层模型可以做到传输的时候都是二进制流的形式,而我们输入的的是字符串的格式,所以在发送字符串之前要先通过encode()编码,在接收处理前通过decode()解码。

5.由于要进行数据通信使用trading方法 进行开线程cmdthread = threading.Thread(target=CmdInterface)
                                                                                cmdthread.start()

6.def getLastData(data): return data[len(data)-1]  定义一个getLastData方法返回获得数据的最后一个字节,这里的[len(data)-1]类似于数组从0开始,所以不是倒数第二个字节。

7.使用split()方法对数据进行切片,这里我们已help为例来看一下如何切片,定义的getConnectData方法通过split()方法按照"   "进行分割,将'connect code is 400'分割成4个字节,然后调用getLastData方法获得数据的最后一个字节。

学习过程中遇到的问题及如何解决:

1.

这问题是因为我们输入的help、connect、exit是字符串格式,而数据的发送接收都是字节格式。

解决方法:在发送字符串之前要先通过encode()编码,在接收处理前通过decode()解码。

2.在切割'exit code is {500}'时,会留下{ }

解决方法在输出print时,使用数组的格式print(data[0]),只留下数字500

3.为什么使用send发送数据时候,服务器端无法获取?

解决方法:在结尾加上回车换行符/r/n。原因在于服务器端接收数据使用的是readline()没有接收到终止的标志,就不会停止接收数据。

还存在的问题:

1.对开线程仍然不理解,单线程和多线程有有什么样的区别。

2.网上的一些方法使用导入re库,用正则表达式配合split()来进行切割,正则表达式的使用不太懂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值