2017-02-19 86 views
1

我有一个小应用程序,其中一个协程将发送数据,另一个协程将接收数据并记录它是否收到确切的传输数据。为什么python asyncio协程暂停在socket.recv(1024)行?为什么while循环无法通过yeild语句?

两个协程都在while循环中。一些如何,反式()协同程序和recv()协同程序不继续前进,当他们打线的产量从XXXXXXX

data, server = yield from recv_sock.recvfrom(1024) 

下面是代码

import asyncio 
import socket 
import time 
import datetime 
import logging 

trans_addr = ('localhost', 5555) 
recv_addr = ('localhost',6666) 

@asyncio.coroutine 
def trans(): 
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    sock.bind(trans_addr) 
    i = 0 
    global sen_data 
    while True: 
     print("hi") 
     sen_data = "HELLO " + str(i) 
     sent = yield from sock.sendto(sen_data.encode(), recv_addr) 
     print(sent) 
     print("hi1") 
     yield from time.sleep(2) 
     i += 1 
     print("hi1") 

@asyncio.coroutine 
def recv(): 
    recv_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    recv_sock.bind(recv_addr) # binding the receiving end to 1.241 and port 6666 
    #recv_sock.setblocking(0) 
    while True: 
     try: 
      print("hello") 
      data, server = yield from recv_sock.recvfrom(1024) 
      print("hello2") 
      if (data): 
       recv_data = data.decode() 

       if (sen_data == recv_data): 
        logging.info("transmitted data :" + sen_data + " is Received as :" + recv_data + " at :" + str(
         datetime.datetime.now()) + '\n') 
        print("transmitted data :" + sen_data + " is Received as :" + recv_data + " at :" + str(
         datetime.datetime.now()) + " from :" + str(server) + '\n') 
       else: 
        logging.critical("Data missed : ") 
        logging.critical("Transmitted data " + sen_data + " is != " + "received data : " + recv_data + '\n') 
        print("data is missing--->") 
        print("Transmitted data " + sen_data + " is != " + "received data : " + recv_data + '\n') 
     except: 
      pass 
      # print("not receiving data due to some fault in the receiving socket") 
      # time.sleep(1) 

loop=asyncio.get_event_loop() 
tasks = [loop.create_task(trans()), loop.create_task(recv())] 
wait_tasks = asyncio.wait(tasks) 
loop.run_forever() 
loop.run_until_complete(wait_tasks) 

输出是:

hello 
hi 

任何人都可以让我知道,为什么协程无法跨越命令的收益?我正在使用python 3.3.2

回答

1

yield fromawait应与协程一起使用。 recvfrom不是一个协程。例如,你可以使用loop.sock_recv()代替:

reader, writer = socket.socketpair() 
writer.setblocking(False) 
reader.setblocking(False) 
await loop.sock_recv(...) 
await loop.sock_sendall(...) 
+0

如果recvfrom的是不是一个协同程序,然后如果我想执行通过套接字接收数据作为协程 - 你的建议是使用loop.sock_recv()。但是,如果我不想将循环作为参数传递给协程,该怎么办?我无法理解,为什么loop通过套接字接收数据时进入了图片。你能详细解释一下吗?我是这个Python世界的新手。 @Udi – ringul

+0

请将此作为一个新问题提问 – Udi

+0

@ringul:因为loop是一个全局变量,所以您可以在代码中的任何位置使用它,而不必将其作为一个paramarter传递。 – Udi