服务器的非阻塞套接字

时间:2015-10-15 00:03:11

标签: python sockets multiprocessing nonblocking

我在stackoverflow.com上检查过几个类似的线程,我想我可能需要为我的服务器脚本打开非阻塞套接字。因为,我不确定这是解决方案问题标题可能是错误的。让我解释一下我的问题。

服务器应用程序等待连接,一旦客户端连接,它将询问服务器ID,之后客户端将要求服务器配置,而客户端将向服务器发送命令以开始测量传输。这是我的代码的简化版本:

def conn_handler(self, connection, address):
    self.logger.info("[%d] - Connection from %s:%d", 10, address[0], address[1])

    sending_measurements_enabled = False
    try:
        while True:
            data = connection.recv(2048)

            if data:
                command = get_command_from_data(data)
            else:
                command = None

            if command == 'start':
                sending_measurements_enabled = True
            elif command == 'stop':
                break
            elif command == 'id':
                connection.sendall(self.id)
            elif command == 'cfg':
                connection.sendall(self.cfg)

            if sending_measurements_enabled:
                connection.sendall(measurement)

    except Exception as e:
       print(e)
    finally:
        connection.close()
        print("Connection closed")

这是客户端脚本:

try:

    sock.sendall(get_id_command)    

    data = sock.recv(2048) # Do I need to wait for response?
    print(data)

    sock.sendall(get_conf_command)

    data = sock.recv(2048)
    print(data)

    sock.sendall(start_sending_measurements)
    data = sock.recv(2048)
    print(data)

    while True:
        sock.sendall(bytes('I do not want this', 'utf-8')) # I would like to keep receiving measurements without this
        data = sock.recv(2048)
        print(data)

finally:
    print('Closing socket...')
    sock.close()

这是我的问题:

当我运行客户端并发送命令以获取ID服务器将返回ID消息时,客户端将发送命令以获取配置,服务器将返回配置消息但是当我发送start命令服务器时将仅发送一个测量和我想connection.recv(2048)会阻止执行,直到服务器获得另一个命令。因此,我在客户端脚本中的while True:循环内添加了该行,这将继续发送(不必要的,无效的)命令,服务器将继续发送测量值。

如何在不从客户端始终发送命令的情况下解决此问题。我希望只能发送一个命令start,服务器将继续发送测量值,并仅在客户端发送stop命令时停止。 此外,如果服务器在发送测量结果时收到idcfg命令,则会先发送idcfg,然后继续发送测量结果。

2 个答案:

答案 0 :(得分:0)

在服务器循环中调用select.select([connection], [connection], [connection])select模块提供更多功能,因此选择您喜欢的)。如果套接字是可读的,请阅读命令并对其作出反应。如果套接字是可写的(并且有数据请求),则发送测量值。

答案 1 :(得分:0)

如果有人需要这个:

public class DBAdapter {
private SQLiteDatabase database;
private Context context;
private DatabaseHelper dbHelper;


private class DatabaseHelper extends SQLiteOpenHelper {

    public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLES_QUERY);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXIST "+TABLE_QUERY);
    }
}

public DBAdapter(Context ctx) {
    this.context = ctx;

}

public DBAdapter open() throws SQLException {
    dbHelper = new DatabaseHelper(context, DBNAME, null,DBVERSION);
    database = dbHelper.getWritableDatabase();
    return this;
}

public Cursor executeQuery() {
    Cursor result = database.rawQuery(YOUR_QUERY, null);
    return result;
}