• Re: 请问网络测量的可研究空间有那些呢?

    是啊,不过我们条件很差,学校不重视IPv6,连环境都没有,上海这边交大复旦

    v6早搞好了。

    如果实验室内部搞IPv6,用linux+zebra/quagga做v6环境,能做试验么?表示怀疑

    “IPv6的网络测量”“IPv4-IPv6共存时期的网络管理”是我想的几个可能的方向。

    SNMPv3 和 IPv6 也是一个方向,不过这个偏向应用?不知道有什么可以创新的..

    【 在 wzy123 (lover) 的大作中提到: 】

    : 你不是也研究IPv6吗?

    2004-07-04
  • 请问网络测量的可研究空间有那些呢?

    曾经看过些pathchar, pathload, VPS, 包对等方面的论文,不过都很老了。

    有没有比较新的研究方向呢?

    谢谢

    2004-07-03
  • [网友资料]hzt

    ID:

    hzt

    所在的学校或公司:

    同济大学

    主要的研究方向:

    网络管理,网络测量,IPv6

    我的email或个人主页:

    houzt@tongji.net

    2004-07-03
  • 用 RRD TOOL 统计 BBS 在线人数

    RRD TOOL的前身是MRTG,搞网管的常用。这个用来统计BBS在线人数也不错。

    使用cron更新图片,显示出来就OK了。

    演示程序:

    http://www.tongji.net/info/

    使用方法:

    创建一个数据库:

    rrdtool create /path/to/web/info/ol.rrd --start `date +%s` \

    --step 60 DS:ol:GAUGE:120:0:2000 RRA:AVERAGE:0.5:1:1440

    再写一个脚本定时更新数据:

    vi /usr/bin/stat.sh

    #!/bin/bash

    rrdtool update /path/to/web/info/ol.rrd `/usr/bin/online`

    rrdtool graph /path/to/web/info/online.gif             \

    --vertical-label "用户数量"                     \

    -t "同济网论坛在线用户统计  `date '+%F %R'`"    \

    DEF:a=/path/to/web/info/ol.rrd:ol:AVERAGE     \

    AREA:a"#00b6e4":"在线用户数量"

    其中/usr/bin/online是输出 '时间戳:在线人数'

    比如:

    # /usr/bin/online

    1084843276:492

    具体参数可以参考 http://www.rrdtool.com/tutorial

    2004-05-18
  • Re: 清华BBS代码的特色

    自己给自己的代码作注释好像自言自语一样,很难受。还时不时需要揣摩别人哪里看不懂,时间长了要人格分裂。

    不写注释也可以有个好的借口:‘真正好的代码不需要注释’。

    一个好办法是把代码放到网上,每个模块由作者简单注释一下功能,代码下边是评论,可以随便什么人发帖子,代码作者也可以进来掺和,就好像php.net在线手册每个函数下的'User Contributed Notes'。

    【 在 flylong (无名) 的大作中提到: 】

    : 你想知道清华BBS代码的特色吗?我来告诉你,那就是坚决不写注释。我说老大,虽说你们的英语水平很好,在变量命名方面做得不错,但也不能不写注释吧,我看过不少源代码,不写注释的就你们一家。你们这样搞让用你们代码的人很郁闷,真不知道你们是怎么想的?难道是想标新�

    2004-04-25
  • [netbbs]批事件处理&聊天室

    批处理就是一系列事件的组合执行:

    class Batch {

    private:

    std::vector<Event> m_events;

    public:

    Batch();

    void add(const Event&);

    void run(Client&);

    };

    一个简单的调用实例,在浏览某个主题中的帖子时候,当浏览到帖子底部继续按下,就是

    浏览下一个帖子,相当于KEY_LEFT+KEY_DOWN+KEY_RIGHT的组合操作(TODO:用户自定义脚本,类似CS里面的一键买枪)

    void ViewPostServlet::processEvent(Event event)

    {

    int response = processWidgetEvent(event);

    if (response == R_DONE) {

    m_client->backward();

    }

    else if (response == R_BLUR) {

    if (event.type == EV_KEY_DOWN || event.type == EV_KEY_PAGE_DOWN) {

    Batch viewNextBatch;

    viewNextBatch.add(Event(EV_KEY_LEFT));

    viewNextBatch.add(Event(EV_KEY_DOWN));

    viewNextBatch.add(Event(EV_KEY_RIGHT));

    viewNextBatch.run(*m_client);

    }

    else if (event.type == EV_KEY_UP || event.type == EV_KEY_PAGE_UP) {

    Batch viewPrevBatch;

    viewPrevBatch.add(Event(EV_KEY_LEFT));

    viewPrevBatch.add(Event(EV_KEY_UP));

    viewPrevBatch.add(Event(EV_KEY_RIGHT));

    viewPrevBatch.run(*m_client);

    }

    }

    }

    提高一下效率,Batch内部优化:

    void Batch::run(Client& client)

    {

    client.doFlush = false;

    unsigned int i;

    for (i = 0; i < m_events.size() - 1; i++) {

    client.processEvent(m_events[i]);

    }

    client.doFlush = true;

    client.processEvent(m_events[i]);

    }

    只有最后一个事件执行的时候才产生输出.

    最简单的聊天室:

    class ChatServlet : public Servlet

    {

    protected:

    static std::vector<Client*> m_client_list;

    static Text m_screen;

    EntryField *entry;

    void say(const String&);

    void quit();

    public:

    void init();

    void update();

    void processEvent(Event);

    };

    m_client_list 保存在线列表, m_screen 保存全局屏幕。

    截屏:

    ---------------------------------------------------------------------------

    [01:19:38] jth来了!

    [01:19:50] jth: hello! 大家好!

    [01:20:03] justin来了!

    [01:20:14] justin: hi jth, 你好!

    [01:20:26] jth: 自言自语 -_-!!

    [01:20:34] justin: :) bye!

    [01:20:34] justin再见!

    [01:20:36] justin来了!

    [01:20:41] justin: i'm back : )

    say what?: 回来了? 呵呵。                                  

    -----------------------------------------------------------------------

    实现代码(比较乱):

    #include "servlets.h"

    std::vector<Client*> ChatServlet::m_client_list;

    Text ChatServlet::m_screen;

    void ChatServlet::init()

    {

    entry = new EntryField();

    entry->setStartRow(m_client->height - 1);

    entry->setStartCol(0);

    entry->setMaxLength(50);

    entry->setLabel("say what?:");

    entry->setLabelStyle(Color(black, white, normal));

    entry->setStyle(Color(white, blue, bold));

    m_client_list.push_back(m_client);

    m_client->clear();

    say(Color(yellow, black, bold) + m_client->name + "来了!" + Color());

    addWidget("1", entry);

    focusWidget("1");

    }

    void ChatServlet::update()

    {

    for (unsigned int ui = 0; ui < m_client_list.size(); ui++) {

    Client* c = m_client_list[ui];

    c->put(Color());

    c->clear();

    int sz = m_screen.numRows();

    for (int i = 0; i < sz; i++) {

    c->put(m_screen[i]);

    c->put("\n");

    }

    c->servlet()->updateWidgets();

    c->flush();

    }

    }

    void ChatServlet::say(const String& message)

    {

    if (m_screen.numRows() == m_client->height - 2)

    m_screen.erase();

    m_screen.append(

    Color(green, black, bold) + "[" + Date().toString("hh:mm:ss") + "] " +

    message);

    update();

    }

    void ChatServlet::quit()

    {

    say(Color(yellow, black, bold) + m_client->name + "再见!" + Color());

    std::vector<Client*>::iterator i = m_client_list.begin();

    while (i != m_client_list.end()) {

    if (*i == m_client) {

    m_client_list.erase(i);

    break;

    }

    i++;

    }

    }

    void ChatServlet::processEvent(Event event)

    {

    if (event.type == EV_KEY_CTRL('C')) {

    quit();

    m_client->backward();

    return;

    }

    int response = processWidgetEvent(event);

    if (response == R_DONE) {

    String message =

    Color() + m_client->name + ": " + entry->text();

    say(message);

    entry->reset(*m_client);

    }

    }

    ------------------------------------------

    最后是 O/R,比如Topic的接口:

    class Topic {

    public:

    virtual int getID() const = 0;

    virtual String getAuthor() const = 0;

    virtual String getTitle() const = 0;

    virtual void setTitle(const String&) = 0;

    virtual int numPosts() const = 0;

    virtual std::vector<int> getPosts() const = 0;

    virtual ~Topic() {}

    };

    然后数据库实现之:

    class CelesteTopic : public Topic {

    private:

    int m_id, m_author_id;

    String m_author;

    String m_title;

    int m_num_posts;

    std::vector<int> m_posts;

    CelesteTopic() {};

    void insertIntoDatabase();

    void loadFromDatabase();

    void saveToDatabase();

    public:

    CelesteTopic(const User& author, const String& title);

    CelesteTopic(int id);

    ~CelesteTopic();

    int getID() const;

    String getAuthor() const;

    String getTitle() const;

    void setTitle(const String&);

    int numPosts() const;

    std::vector<int> getPosts() const;

    };

    最后:

    [bbs]->[CelesteBBS]

    |         |

    Topic  CelesteTopic

    2004-04-20
  • bbs server gui design

    bbs project statistics

    ------------------------

    31 c++ source files.

    27 c++ header files.

    4973 总计 lines code.

    所有复杂可控图形元素继承自 Widget 接口

    class Widget {

    public:

    Widget();

    virtual int processEvent(Client&, Event);

    virtual ~Widget();

    };

    举例:

    class Menu : public Widget {

    private:

    std::vector<MenuItem> _menu_items;

    int _start_row;

    int _start_col;

    int _width;

    int _select;

    void draw(Client&, bool force);

    public:

    Menu() : _start_row(-1), _start_col(-1), _width(0), _select(0) { }

    void setStartRow(int r) { _start_row = r; }

    void setStartCol(int c) { _start_col = c; }

    void setWidth(int w) { _width = w; }

    int getResult()  { return _select; }

    void addItem(int key, char shortCut, String label);

    int processEvent(Client&, Event);

    };

    另例:

    class VI : public Widget {

    private:

    Text m_text;

    int m_width, m_height, m_offset, m_row, m_col;

    void view_update_footer(Client& client, bool force);

    void view_update_body(Client& client, bool force);

    void model_update_col(Client& client);

    void on_key_right(Client& client);

    void on_key_left(Client& client);

    void on_key_up(Client& client);

    void on_key_down(Client& client);

    void on_key_home(Client& client);

    void on_key_end(Client& client);

    void on_key_del(Client& client);

    public:

    VI();

    void setWidth(int);

    void setHeight(int);

    int processEvent(Client&, Event);

    };

    再例:

    class Notepad : public Widget {

    private:

    Text m_text;

    int m_width, m_height, m_offset, m_row, m_col;

    void view_update_footer(Client& client, bool force);

    void view_update_body(Client& client, bool force);

    void model_update_col(Client& client);

    public:

    Notepad();

    void setWidth(int);

    void setHeight(int);

    int processEvent(Client&, Event);

    };

    app 层调用:

    比如浏览text控件的接口设计和调用:

    class TextViewer : public Widget {

    private:

    Text m_text;

    int m_width, m_height, m_offset;

    void view_update_footer(Client& client, bool force);

    void view_update_body(Client& client, bool force);

    public:

    TextViewer();

    void setWidth(int);

    void setHeight(int);

    int processEvent(Client&, Event);

    Text& text() {

    return m_text;

    }

    };

    void state_topic_content(Client& client, Event event)

    {

    if (event.type == EV_INIT) {

    TextViewer *textViewer = new TextViewer;

    int topicid = client.getIntProperty("topicid");

    BBS::instance()->loadTopicContent(topicid, textViewer->text());

    client.setController(textViewer);

    }

    int response = client.processWidgetEvent(event);

    if (response == R_DONE) {

    client.backward();

    }

    }

    -----------------

    目前设计单一状态单一控件

    如果gui部分要求复杂,可以扩展为单状态多控件,每个控件可以用字符串指定id

    或者用整形指定id,根据id设定focus顺序,生成如下界面

    username: [__________] <-entry_field0

    password: [__________] <-entry_field1

    email:    [__________] <-entry_field2

    ..

    [submit] [cancel]  <-button0 button1

    ..

    根据操作在各个控件间转换阵地

    可以使用类似frame或者form可容器控件管理

    ....

    2004-04-03
  • Re: 关于合力开发第三套bbs访问接口的建议(草稿)

    这个先支持一下:)

    【 在 peacock.bbs@ytht.net (孔雀@ytht) 的大作中提到: 】

    : 目前国内的bbs基本都是火鸟系统,基于telnet协议和http协议。

    : 1)telnet接口:核心思想是将远程的用户端虚拟为一个键盘和一个虚拟显示终端,

    : 这种接口的所有的交互都是基于过程;每个用户对应一个socket连接、一个进程。

    : ...................

    2004-03-28