作者: yylogo

  • S-K-YServer beta版发布

      此次发布的版本,已经成为真正的服务器雏形了,按照Liun的话,成功独立出线程池,以后写Ftp服务器阿,写一些本地的文件处理阿,之类的都能够直接调用线程池中的函数了,也就是说线程池完全独立出来了,和服务器已经没有直接的关系了,惟一的关系就是服务器要调用线程池的函数。

      这一次将线程池的锁分配到线程,每个线程一把锁,然后用两个列队来报存正在工作的线程和空闲线程,当然,每个列队自身也有一把锁,不然不久K.O.了。
      然后本次升级提升了服务器的健壮性,当遇到非HTTP协议时不会自动退出了(我自己写了个客户,只是连接服务器,然后就关闭套接口,结果服务器就崩溃了。),然后我想想还有什么更新。。
      但是还需要修改的地方是:增加当线程用完时,能够再分配指定数量的线程;第二,使用更快的列队(如:堆)。
      哈哈,本次升级之后已经能够使用了,但是我还能想到一个漏洞,不是服务器,而是自己写一个客户端程序,请求文件../../../(因为8080只能是管理员打开,所以就能够读取所有文件了,这是一个很棘手但很好处理的漏洞。)
      暂时先不修复,因为OI我一个星期没一点动静了,该OI了,虽然明天开学,虽然今天没有OI,但是还是挺开心的,服务器写到了这个程度(我很自豪!)。

  • Ubuntu WebQQ桌面化

    转自Ubuntu中文官方..
    桌面化webqq可实现将webqq最小化到通知区域并且来消息时提示

    1.安装google chrome浏览器

    2.安装alltray sudo apt-get install alltray

    3.新建一个启动器,名称随便,命令为 “/usr/bin/alltray” -t 5 -s /opt/google/chrome/google-chrome –app=”http://web.qq.com“

    4.若来消息不提示请参考会员wobu的文章 http://forum.ubuntu.org.cn/viewtopic.php?f=73&t=257749&start=0

  • 网络的漏洞

      我先有话在先,我现在15岁,高一,只是对Linux, Unix有些爱好,如果说的什么都不是千万不要喷。。
      我是在看Unix网络编程 第一卷 第三版 38页的时候想到的一个思路,当然我不可能实现咯……就是说TCP在关闭时会有一个TIME_WAIT状态,这个状态是为了两个理由存在的:1,实现可靠的TCP全双工连接的终止;2,允许老的重复分解在网络中消逝。看到这里和下文我就想了,数据被传输是通过路由的对吧,也就是可以表示成:
    网络的漏洞 - NeWorldMaker - My S-K-Y
      (我习惯的画图工具Flash 没装, 就用的Windows 7的图画工具)
      这样是没有错的吧? 然后针对TIME_WAIT存在的第二个理由,消逝的理由就是防止数据在下一次连接中出现,避免不必要的问题对吧,那我就想了,如果我能控制路由的话,在分节消逝之后再让它出现在网络中会怎么样呢?
      把这个思路再进一步修改一下,当数据经过我的路由时我对它进行拦截+分析+修改,然后发送过后的数据到目的地去,就能够让网络不正常吧?当然咯,我这个想法很天真,因为全世界不止我这一台路由,但是如果有数据从我这台路由上通过的话我能否这样实现呢?
      如果可以的话,我会再把这个玩狠一点:当有数据经过我的路由器时,将数据拦截下来,如果是ACk分节的话,将ACK分节发送给目的地。然后再发送(以发送源的身份)一个FIN n+1(n是ack的值),然后对源(以目的的身份)发送一个FIN;如果不是ACK分节就更好,直接对双发发送FIN分节。
      嘿嘿,总之就是说接收到分节,不是直接将其转发,而是进行分析之后对双发发送FIN分节,如图:
    网络的漏洞 - NeWorldMaker - My S-K-Y
      思路大概就是这样,但是这一切的前提都是我能够控制路由器,而且有数据经过我的路由器,最重要的是我非常无聊。。
      思路我先留着,看以后能实现不,控制路由。。暂时还有点远,现在是NOIp。
  • TYVJ 第三题 滑雪 解题报告

    题目:
    背景 Background
      成成第一次模拟赛 第三道
    描述 Description
        trs喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
      例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。
    输入格式 Input Format
      输入文件

    第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
    第2..r+1行:每行c个数,表示这个矩阵。
    输出格式 Output Format
      输出文件

    仅一行: 输出1个整数,表示可以滑行的最大长度。
    我的解答:
      我以为题目就是要找出连续的最大的数字呢, 就是说顺着路径找出最大的~! 一提交,, 40分..
    #include <stdio.h>
    int map[100][100];
    int n, m;

    int getv(int x, int y)
    {
            if(x < 0 || x >= m || y < 0 || y >= n){
                    return –1;
            }
            return map[x][y];
    }

    int main(void)
    {
            int i, j;
            int k;
            int a, b;
    //      freopen(“abc.txt”, “r”, stdin);
            scanf(“%d%d“, &m, &n);
            for(i = 0; i < m; i++){
                    for(j = 0; j < n; j++){
                            scanf(“%d“, &map[i][j]);
                            if(map[i][j] == 1){
                                    a = i;
                                    b = j;
                            }
                    }
            }
            k = 1;
            while(k < m * n){
                    if(getv(a – 1, b) == k + 1){
                            a = a – 1;
                            k++;
                            continue;
                    }
                    if(getv(a + 1, b) == k + 1){
                            a = a + 1;
                            k++;
                            continue;
                    }
                    if(getv(a, b – 1) == k + 1){
                            b = b – 1;
                            k++;
                            continue;
                    }
                    if(getv(a, b + 1) == k + 1){
                            b = b + 1;
                            k++;
                            continue;
                    }
                    break;
            }
            printf(“%d\n“, k);
    //      getch();
            return 0;
    }


      后来又以为是求最大的顺序(不一定是1 2 3, 也可以是1 3 4,)
     就是跳跃式前进的, 结果是30分..




    #include <stdio.h>
    int map[100][100];
    int n, m;

    int getv(int x, int y)
    {
            if(x < 0 || x >= m || y < 0 || y >= n){
                    return –1;
            }
            return map[x][y];
    }

    int main(void)
    {
            int i, j;
            int k, t, s;
            int a, b;
            int d, f;
    //      freopen(“abc.txt”, “r”, stdin);
            scanf(“%d%d“, &m, &n);
            for(i = 0; i < m; i++){
                    for(j = 0; j < n; j++){
                            scanf(“%d“, &map[i][j]);
                            if(map[i][j] == 1){
                                    a = i;
                                    b = j;
                            }
                    }
            }
            k = 1;
            while(k < m * n){
                    s = 10000000; 
                    t = getv(a – 1, b);
                    if(t > k && t < s){
                            d = a – 1;
                            f = b;
                            s = t;
                    }
                    t = getv(a + 1, b);
                    if(t > k && t < s){
                            d = a + 1;
                            f = b;
                            s = t;
                    }
                    t = getv(a, b – 1);
                    if(t > k && t < s){
                            d = a;
                            f = b – 1;
                            s = t;
                    }
                    t = getv(a, b + 1);
                    if(t > k && t < s){
                            d = a;
                            f = b + 1;
                            s = t;
                    }
                    if(t == k){
                            break;
                    }
                    a = d;
                    b = f;
                    k = s;
            }
            printf(“%d\n“, k);
    //      getch();
            return 0;
    }
  • TYVJ 第二题 第K极值

      思路很简单, 将数据进行一次排序, 取第t个和倒数第t个, 然后倒数第t个减去第t个, 再判断差是否为素数..
      听前辈们说NOIp不能使用库函数qsort, 而我一老使用, 为了避免考试0分的情况, 这里就自己写了一个快排, 当快拍的元素少于15个时就使用插入排序进行排序.
      代码如下:
    #include <stdio.h>
    #include <math.h>
    #define swap(a, b) do{\
            if(!((a) ^ (b))){\
                    break;\
            }\
            (a) ^= (b);\
            (b) ^= (a);\
            (a) ^= (b);\
    }while(0)
    unsigned long map[10000];

    int compare(int a, int b)
    {
            return a – b;
    }

    void insert_sort(unsigned long *a, int start, int end)
    {
            int i, j;
            int key;
            for(i = start + 1; i <= end; i++){
                    key = a[i];
                    for(j = i – 1; j >= 0 && compare(key, a[j]) < 0; j–){
                            a[j + 1] = a[j];
                    }
                    a[j + 1] = key;
            }
    }

    int getmiddle(unsigned long a[], int s, int e)
    {
            int m;
            m = (s + e) / 2;
            if(compare(a[m], a[s]) < 0){
                    swap(a[m], a[s]);
            }
            if(compare(a[s], a[e]) > 0){
                    swap(a[s], a[e]);
            }
            if(compare(a[m], a[e]) > 0){
                    swap(a[m], a[e]);
            }
            return m;
    }

    void quick_sort(unsigned long *a, int start, int end)
    {
            int middle;
            int len = end – start + 1;
            int i, j;
            unsigned key;
            if(len <= 15){
                    insert_sort(a, start, end);
                    return;
            }
            middle = getmiddle(a, start, end);
            key = a[middle];
            swap(a[end – 1], a[middle]);
            i = start;              //除去三值的头
            j = end – 1;           //除去三值的尾
            while(i < j){
                    while(compare(a[++i], key) < 0){
                    }
                    while(compare(a[–j], key) > 0){
                    }
                    if(i < j){
                            swap(a[i], a[j]);
                    }
            }
            swap(a[i], a[end – 1]);
            quick_sort(a, start, i – 1);
            quick_sort(a, i + 1, end);
    }

    int isprime(unsigned long n)
    {
            int limit = sqrt(n);
            int i;
            if(n == 1 || n == 0){
                    return 0;
            }
            for(i = 2; i <= limit; i++){
                    if(n % i == 0){
                            return 0;
                    }
            }
            return 1;
    }

    int main(void)
    {
            int n, t, i;
            unsigned long ans;
            scanf(“%d%d“, &n, &t);
            for(i = 0; i < n; i++){
                    scanf(“%d“, &map[i]);
            }
            quick_sort(map, 0, n – 1);

            ans = map[n – t] – map[t – 1];
            if(isprime(ans)){
                    printf(“YES\n“);
            }else{
                    printf(“NO\n“);
            }
            printf(“%d\n“, ans);

            return 0;
    }
  • TYVJ的原题不能刷了,, 只好去主站刷别的题目..

      哎,, TYVJ的原题不能刷了,, 只好去主站刷别的题目..
      再一个又要开学了, 计算机的分量要比原来轻很多很多了~! 希望这个学期能够取得好成绩, 和同学之间相处融洽, 然后计算机方面更上一层楼, (Linux 也好, 内核也好, 网络也好, OI更好..)
      今天把Fedora删了,, Fedora的桌面确实不如Ubuntu,, 还是用Ubuntu算了, 不过装没装好, 明天再装一次.

  • Fedora 12 安装 unrar

    [root@Zqynux yylogo]# yum -y install unrar
    已加载插件:axelget, fastestmirror, refresh-packagekit
    Loading mirror speeds from cached hostfile
      fedora: mirrors.163.com
      updates: mirrors.163.com
    设置安装进程
    No package unrar available.
    无须任何处理
    warning: /var/tmp/rpm-tmp.OEJ6CN: Header V3 RSA/SHA256 signature: NOKEY, key ID 8fcff4da
    Preparing…                ########################################### [100%]
       1:rpmfusion-free-release ########################################### [100%
    warning: /var/tmp/rpm-tmp.m0szEk: Header V3 RSA/SHA256 signature: NOKEY, key ID 8dc43844
    Preparing…                ########################################### [100%]
       1:rpmfusion-nonfree-relea########################################### [100%]
    [root@Zqynux yum.repos.d]# yum install unrar -y
    已加载插件:axelget, fastestmirror, refresh-packagekit
    Loading mirror speeds from cached hostfile
      fedora: mirrors.163.com
      rpmfusion-free: mirrors.163.com
      rpmfusion-free-updates: mirrors.163.com
      rpmfusion-nonfree: mirrors.163.com
      rpmfusion-nonfree-updates: mirrors.163.com
      updates: mirrors.163.com
    设置安装进程
    解决依赖关系
    –> 执行事务检查
    —> 软件包 unrar.i686 0:3.8.5-5.fc12 将被 升级
    –> 完成依赖关系计算

    依赖关系解决

    ============================================================================
     软件包    架构     版本                仓库                           大小
    ============================================================================
    正在安装:
     unrar     i686     3.8.5-5.fc12        rpmfusion-nonfree-updates     105 k

    事务概要
    ============================================================================
    安装       1 软件包
    更新       0 软件包

    总文件大小:105 k
    下载软件包:
    [1/1]Ok,we will try to use axel to download this big file:107392
    Target already exists,skip to next file!
    warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 signature: NOKEY, key ID a3a882c1
    rpmfusion-nonfree-updates/gpgkey                     | 3.4 kB     00:00 … 
    导入 GPG 密钥 0xA3A882C1 "RPM Fusion nonfree repository for Fedora (12) <rpmfusion-buildsys@lists.rpmfusion.org>",来自 /etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-nonfree-fedora-12-i386
    运行 rpm_check_debug 
    执行事务测试
    完成事务测试
    事务测试成功
    执行事务
    警告:自上次 yum 事务以来 RPMDB 已变动。
      正在安装       : unrar-3.8.5-5.fc12.i686                              1/1 

    已安装:
      unrar.i686 0:3.8.5-5.fc12                                                 

    完毕!

  • NOIp 2007 第三题 矩阵取数游戏

      题目困扰了我很久,后来才知道,该怎么解题。
      这题说是说矩阵取数,但是仔细看看能够知道,和矩阵没什么关系,只每行的最大值有关,因为每行之间的最大没有任何关系。那么就将矩阵取数转变成了对数组取数,对数组取数很容易看出来是DP,DP方程如下:f[i][j] = max( 2 map[i] + 2  f[i + 1][j], 2  map[j] + 2  f[i][j – 1] )。最初状态是f[i][i] = 2 map[i]。f[i][j]的是i~j之间的能够取的最大值。
      方程我还解释一下,比如第一个数据吧:

         2 3
         1 2 3
         3 4 2
      我只说明第一行,f[0][0] = 2, f[1][1] = 4, f[2][2] = 6, 然后f[0][1] = max( 2 map[0] + 2 f[1][1], 2 map[1] + 2 f[0][0] ) = 10,也就是说"1 2"这两个数据应该先取1再去二,然后f[1][2] = 14.f[0][2] = 82..
      就是这样的思路,其实思路我三天前就有了,但是因为数据太大,2^80以上,用long long 都装不下,那只能使用高精度了,但是实在很难下手啊NOIp 2007 第三题 矩阵取数游戏 - NeWorldMaker - My S-K-Y。
      怎么办?没办法了,只好先用int来写,然后封装起来,再把int改成高精度,啥?这句话没看懂?
      意思就是说我先写了下面第一段代码,没用高精度,只得了40分,但是下面这个代码的框架封装的很好,然后直接将几个函数修改一下就能够使用高精度了:
    #include <stdio.h>
    #include <string.h>
    /
     ===============对使用"数"类型的封装=============== /
    typedef struct{
            int num;
    }num;

    void give(num a, int n)
    {
            a->num = n;
    }

    void add(num a, num b)
    {
            a->num += b->num;
    }

    void addnum(num a, int n)
    {
            a->num += n;
    }

    void copy(num a, num b)
    {
            a->num = b->num;
    }

    int compare(num a, num b)
    {
            return a->num – b->num;
    }

    void output(num a)
    {
            printf("%d\n", a->num);
    }

    / ===============程序的实现=============== /

    num f[80][80];
    num ans;
    num s1, s2;
    int map[80];

    void srch(int n)
    {
            int i, k;
            num t;
            memset(f, 0, sizeof(f));
            for(i = 0; i < n; i++){
                    give(&f[i][i], map[i]);
                    addnum(&f[i][i], map[i]);
            }
            for(k = 1; k < n; k++){
                    for(i = 0; i < n – k; i++){
                            copy(&s1, &f[i + 1][i + k]);
                            addnum(&s1, map[i]);
                            copy(&s2, &f[i][i + k – 1]);
                            addnum(&s2, map[i + k]);
                            if(compare(&s1, &s2) < 0){
                                    t = &s2;
                            }else{
                                    t = &s1;
                            }
                            copy(&f[i][i + k], t);
                            add(&f[i][i + k], t);
                    }
            }
    }

    int main(void)
    {
            int m, n;
            int i, j;
            memset(&ans, 0, sizeof(ans));
            scanf("%d%d", &n, &m);
            for(i = 0; i < n; i++){
                    for(j = 0; j < m; j++){
                            scanf("%d", &map[j]);
                    }
                    srch(m);
                    add(&ans, &f[0][m – 1]);
            }
            output(&ans);
            return 0;
    }
      高精度的代码等下发上来。

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    /
     =====================高精度实现部分===================== /
    #define max(a, b) ((a)>(b)?(a):(b))
    #define TOTAL 40
    const int used = 100000000;
    #define bits ((int)log10(used))
    typedef struct{
            int num[TOTAL];
            int len;
    }num;

    static void deal(num a)
    //防止高精度的漏洞.
    //如:used = 10000, give(a, 10000), give(a, 1), give(b, 10000), add(a, b)
    //此时a为20001而不是10001 
    {
            int i;
            for(i = a->len; i < TOTAL; i++){
                    a->num[i] = 0;        
            }
    }

    void give(num a, int n)
    {
            int i;
            for(i = 0; n; i++){
                    a->num[i] = n % used;
                    n /= used;
            }
            a->len = i;
            deal(a);
    }

    void add(num a, num b)
            //这里有个bug, a和b 不能相同
    {
            int i;
            int len = max(a->len, b->len);
            int re = 0;
            
            for(i = 0; i < len; i++){
                    a->num[i] += b->num[i] + re;
                    re = a->num[i] / used;
                    if(re > 0){
                            a->num[i] %= used;
                    }
            }
            a->len = len;
            if(re > 0){
                    a->len++;
                    a->num[i] = re;
                    //掉了 a->num[i] = re; 这一行
            }
    }

    void addnum(num a, int n)
    {
            int i;
            int re = 0;
            for(i = 0; n; i++){
                    a->num[i] += (n % used) + re;
                    n /= used;
                    re = a->num[i] / used;
                    if(re > 0){
                            a->num[i] %= used;
                    }
            }
            a->len = max(i, a->len);
            if(re > 0){
                    a->num[i] += re;
                    //写成了=re; 
                    a->len = max(i + 1, a->len);
            }
    }

    void copy(num a, num b)
    {
            memcpy(a, b, sizeof(num));
    }

    int compare(num a, num b)
    {
            if(a->len != b->len){
                    return a->len – b->len;
            }

            int i;
            for(i = a->len – 1; i >= 0; i–){
                                    //是i–不是i++ 
                    if(a->num[i] != b->num[i]){
                            return a->num[i] – b->num[i];
                    }
            }
            return 0;
            return a->num – b->num;
    }

    void output(num a)
    {
            int i;
            int len = a->len,
    num = a->num;
            printf("%d", num[len – 1]);
            len–;
            for(i = len – 1; i >= 0; i–){
                    printf("%.d", bits, num[i]);
            }
            printf("\n");
    }

    / =====================主函数部分===================== /

    num f[80][80];
    num ans;
    num s1, s2;
    int map[80];

    void srch(int n)
    {
            int i, k;
            num
    t;
            memset(f, 0, sizeof(f));
            for(i = 0; i < n; i++){
                    give(&f[i][i], 2 * map[i]);
            }
            for(k = 1; k < n; k++){
                    for(i = 0; i < n – k; i++){
                            copy(&s1, &f[i + 1][i + k]);
                            addnum(&s1, map[i]);
                            copy(&s2, &f[i][i + k – 1]);
                            addnum(&s2, map[i + k]);

                            if(compare(&s1, &s2) < 0){
                                    t = &s2;
                            }else{
                                    t = &s1;
                            }
                            copy(&f[i][i + k], t);
                            add(&f[i][i + k], t);
                    }
            }
    }

    int main(void)
    {
            int m, n;
            int i, j;
            memset(&ans, 0, sizeof(ans));
            scanf("%d%d", &n, &m);
            for(i = 0; i < n; i++){
                    for(j = 0; j < m; j++){
                            scanf("%d", &map[j]);
                    }
                    srch(m);
                    add(&ans, &f[0][m – 1]);
            }
            output(&ans);
            return 0;
    }

  • Http服务器正式版

      经过昨天一晚上的奋斗+今天一早上的奋斗,服务器总算是能够真正的使用了。
    昨晚上:
      今天晚上拼了命在写服务器,打算把进程池写出来,反复的翻Unix 环境高级编程,天啊,进程之间的通信真的很麻烦,没对进程都需要两个管道(如果需求移植能力强的话是2个,不然可以是1个。)然后我就放弃了,考虑线程池,但是不知道怎么样调度线程,后来翻到了线程可以单独接收信号,打算从这里下手,写了好久,把线程锁,信号集都用上了,但是还是Failed了。最后打算直接使用线程锁+数据的正负性来下手(程序的效率不会高的,因为每个线程都有可能加锁然后发现数值错误,再解锁。),正在撰写中。
      忽然想到了另外一种方法,用进程池,之间直接使用信号来管理,思路不错,但是等线程池失败了再考虑。
      线程池的成功了,不过前面的一种方法,就是使用信号的,也不一定失败了,因为我之前写的时候掉了一个函数,现在再试试这种效率高的方法。
      很可惜,还是失败了,那我就先用那种效率低的方法吧。。
      最后发现竟然是机子的问题,我把服务客户的函数去掉了,不过不知道为什么,accept只能接受一个客户请求。。只好明天早上再写了(现在已经00:30了.)
    今天早上:
      把需要的函数加上后,尝试了昨天的两种线程调度的方法,第一种还是失败了,sigwait的用法还是不够清楚,我就直接使用了第二种,使用线程锁,主线程一直锁上,tmpsock=-1,然后其他的线程再为锁而睡眠,当主线程接收到客户,就把全局变量tmpsock设置成套接字文件描述父,就把锁释放,然后马上夺取。然后其他线程也会夺取这个线程锁,主线程得到锁之后判断tmpsock是否为-1,如果是就返回主函数,否则放锁再夺取,其他线程判断tmpsock是否为-1,如果是就放缩,否则就把这个套接字设为自己的,然后置tmpsock为-1,然后对客户发送Html文件。
      此方案已经成功了,不过效率可能不高,因为可能一直是主线程得锁,又放锁;还可能是一个线程得到套接字文件描述符之后,其他的线程反反复复的再得锁又防锁(解锁)。
      但总之这个方案已经实现了,自己挺自豪的,这样服务器就成为了真正的并发服务器。
  • Http 服务器 beta 0.1 版

      修改了一两个小时,把文件的源代码由一个分成了几个,每个文件完成各自的功能,(有点模块化的感觉,哈哈)。然后自然是写了一个Makefile,不过只有2行代码咯,关键是可以捕捉信号了,就是说可以处理子进程僵死的问题了,成功升级为真正的并发服务器,关于这点我打算写成线程池或进程池,可以可以提高服务器的性能。记得僵死进程的时候,一下子30几个僵死进程,在那儿吓死人!!!

    S-K-Y Http 服务器 beta 0.0 – S-K-Y Http 服务器 beta 0.1
    1.增加自动显示首页功能。
    2.增加404 页面无法找到功能。
    3.增加信号捕捉功能, 处理服务器产生的僵死进程。
    4.使服务器的代码更具可读性。
    5.增加了Makefile文件。