“ OSError:[Errno 24]打开的文件太多:”和来自aiocoap context.request()的套接字

时间:2018-06-20 15:16:08

标签: python raspberry-pi python-asyncio coap

您好,我正在研究树莓派PI,它应该从连接到该PI的传感器连续发送数据,所以这是我的脚本:

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import org.json.JSONArray;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ListView listView = (ListView) findViewById(R.id.listView);
        // Make server logic inside Async Task.
        new AsyncTaskHandler(new OnFinishCallback() {
            @Override
            public void onSuccess(List<String> result) {
                CustomAdapter customAdapter = new CustomAdapter(result);
                listView.setAdapter(customAdapter);
            }
        }).execute("http://anontech.info/courses/cse491/employees.json");
    }

    class CustomAdapter extends BaseAdapter {

        private final List<String> employees;

        public CustomAdapter(List<String> result) {
            this.employees = result;
        }

        @Override
        public int getCount() {
            return employees.size();
        }

        @Override
        public String getItem(int position) {
            return employees.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        // Use ViewHolder pattern.
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            final ViewHolder viewHolder;
            if (view !=null){
                viewHolder = (ViewHolder) view.getTag();
            }else {
                view = getLayoutInflater().inflate(R.layout.customlayout, null);
                viewHolder = new ViewHolder();
                viewHolder.textView = (TextView) view.findViewById(R.id.employeeName);
                view.setTag(viewHolder);
            }
            viewHolder.textView.setText(getItem(i));
            return view;
        }


        // Should use View Holder pattern
        public class ViewHolder{
            TextView textView;
        }
    }


    /**
     * Static inner class to handle memory leak with inner class.
     */
    public static class AsyncTaskHandler extends AsyncTask<String, Void, List<String>> {
        private final OnFinishCallback callback;
        public AsyncTaskHandler(OnFinishCallback callback) {
            this.callback = callback;
        }

        @Override
        protected List<String> doInBackground(String... args) {
            List<String> result = new ArrayList<>();
            try {
                URL url = new URL(args[0]);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                String line = "";
                String data = "";
                while (line != null) {
                    line = bufferedReader.readLine();
                    data = data + line;
                }

                JSONArray array = new JSONArray(data);
                for (int i = 0; i < array.length(); i++) {
                    String employeeName = array.getJSONObject(i).getString("name");
                    result.add(employeeName);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }

        @Override
        protected void onPostExecute(List<String> result) {
            callback.onSuccess(result);
        }
    }

    public interface OnFinishCallback{
        void onSuccess(List<String> result);
    }
}

但是在运行20/25分钟后,我出现此错误:

import logging
import asyncio
from grovepi import*

import time
import json

from aiocoap import *

logging.basicConfig(level=logging.INFO)

def createMsg( file,value ) :
    f= open(file + "Config.json")
    data = json.load(f)
    f.close()
    data["timestamp"] = str(round(time.time(), 3))
    data["value"] = value
    return json.dumps( data )

async def main():

    #analog
    soundSensorPort=0
    lightSensorPort=1

    #digital
    motionSensorPort=2
    tempSensorPort=2
    ultrasonicSensorPort=5
    pinMode(tempSensorPort, "INPUT")

    while True:
        context = await Context.create_client_context()

        await asyncio.sleep(2)
        [ tempSensorValue, humiditySensorValue ]  = dht(tempSensorPort, 0)
        tempMsg = createMsg( "temperatureSensor", tempSensorValue)
        humidityMsg = createMsg( "humiditySensor", humiditySensorValue)

        payloadTemp = tempMsg.encode('utf-8')
        payloadHumidity = humidityMsg.encode('utf-8')
        requestTemp = Message(code=PUT, payload=payloadTemp)
        requestHumidity = Message(code=PUT, payload=payloadHumidity)

        requestTemp.opt.uri_host = '129.6.60.38'
        requestHumidity.opt.uri_host = '129.6.60.38'

        requestTemp.opt.uri_path = ("other", "sensors","temperature")
        requestHumidity.opt.uri_path = ("other", "sensors","humidity")

        responseTemp = await context.request(requestTemp).response
        responseHumidity = await context.request(requestHumidity).response

        print('Result: %s\n%r'%(responseTemp.code, responseTemp.payload))
        print('Result: %s\n%r'%(responseHumidity.code, responseHumidity.payload))

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

这真的很奇怪,因为我只是在读取文件并将其加载到'f'之后关闭了文件,所以如果有人有想法,这将非常有用

编辑0: 运行File "clientPUT.py", line 84, in <module> File "/usr/lib/python3.5/asyncio/base_events.py", line 466, in run_until_complete File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step File "clientPUT.py", line 63, in main File "clientPUT.py", line 27, in createMsg OSError: [Errno 24] Too many open files: 'temperatureSensorConfig.json' 返回:

sudo ls -l /proc/4223/fd

1 个答案:

答案 0 :(得分:4)

鉴于CoAP既可以充当服务器又可以充当客户端,因此即使没有请求活跃,aiocoap上下文也可以对包做出反应,并且可以持续使用.shutdown()协程关闭它。根据平台的不同,这通常意味着每个上下文至少创建一个服务器套接字,如果创建的上下文过多,可能导致文件描述符耗尽。

除极少数例外外,应用程序没有理由创建多个上下文。由于这似乎是一种常见的误解,因此正在对文档进行更新以使这一点更加明确。