2017-08-10 43 views
0

我想在Python中编写我的第一个客户端服务器应用程序。我的客户端向服务器端发送不同的命令。例如,其中之一是用于在命令shell中执行命令。它看起来像:如何从Python中分离接收到的数据?

client.send("execute".encode("utf-8")) 
client.send(command.encode("utf-8")) 

在服务器端,我想收到这样说:

data = client.recv(BUFF_SIZE).decode("utf-8").strip() 
if data == "execute": 
    command = client.recv(BUFF_SIZE).decode("utf-8").strip() 
    ... 

,但我得到“执行{}命令”字符串“数据”变量,= =“执行”条件未满足。我是客户端 - 服务器应用程序的新手,不知道如何正确执行。我做错了什么?

if data.split("{")[0] == "execute" 

解释:

data = "execute{command}" 
print data.split("{")[0] 

打印

"execute" 

由于数据是一个字符串,你

+0

@ 3D1T0R在这种情况下,我得到一个字符串“execute \ n {command}”,但仍然在同一个'data'变量中。 –

回答

0

,你可以通过改变服务器代码的if语句来解决这个问题可以使用split方法将字符串拆分为使用“{”字符的列表。

这样:

data.split("{") 

将返回

["execute", "commmand}"] 

因为你要 “执行” 你把索引0列表

+0

不,我的意思是,我想将这两条消息分别接收到不同的变量中。而我的问题是,recv函数将两个消息都放在一个'data'中。 –

+0

什么是BUFF_SIZE设置为? – AllenMoh

+0

它被设置为1024字节 –

4

要认识到的一点是,TCP是一个字节流。您从TCP获得的保证是您发送的字节将以相同的顺序到达。如果字节流表示一系列命令,则不能保证字节将以与您发送的内容对齐的块形式到达。 您可能会发送:“执行”,“命令” 并接收“e”“xecuteco”“mmand”。

(是的,这是非常不可能的,但由于nagle算法的缘故,接收“executecommand”的可能性很大,但我离题了一点,就是为了编写健壮的代码,你的数据分成小块)

因此,你需要决定的第一件事情是请求字节流如何分割成请求,以及响应字节流如何分割成响应。在请求内部,您需要确定其内部结构。

假设你决定该请求看起来像: “动词参数1参数2 ...... paramN \ n”个 即:

  1. 请求是不换行字节序列,然后是换行符
  2. 该请求是由一个初始动词(非空格字符),接着是零个或多个参数

由于协议本身现在有超过TCP的附加层,则最好使用abstracti来编码这上。一些类似于:

class Request(object): 
    def __init__(self, verb, *args): 
     self.verb = verb 
     self.args = [str(x) for x in args] 

class Client(object): 
    def __init__(self, sock): 
     self.sock = sock 
     self.rxbuf = '' 

    def send_request(self, req): 
     req_str = req.verb 
     if req.args: 
      req_str += ' ' + ' '.join(req.args) 
     req_str += '\n' 
     self.sock.sendall(req_str.encode("utf-8")) 

class Server(object): 
    def __init__(self, sock): 
     self.sock = sock 
     self.rxbuf = '' 
    def read_request(self): 
     while True: 
      s = self.rxbuf.split('\n', 1) 
      if len(s) == 2: 
       req_str = s[0] 
       self.rxbuf = s[1] 
       req_lst = req_str.split(' ') 
       return Request(req_lst[0], *req_lst[1:]) 
      data = self.sock.recv(BUF_SIZE).decode("utf-8") 
      self.rxbuf += data 

当然,这必须通过的回答将如何看起来像,以及如何将输入的字节流描绘成响应序列的决定的补充。我试图让这段代码的主要观点是,

  1. 你读取的字节
  2. 你积累他们
  3. 尝试看看,如果到目前为止,你已经得到了的东西是一个完整的请求
  4. 如果是的话 - 分析,并将其余的下一次

这假设请求相当小,你不必流它们,这是一个更高级的话题。

+0

非常感谢!我发现你是一个有知识的人,你能帮助或指导我解决更多问题吗?为了客户端和服务器,双方必须打开必要的端口。除了手动打开它,没有更多的解决方案? –

相关问题