KEEP K.I.S.S.

tk's blog

Debian安装后的一些配置备注

由于Sabayon升级后一直有一个奇怪的locale问题,最近又重新安装了 Debian Wheezy,这里记录一下安装后需要做的一些配置工作。

1. 修改源

网上搜到修改源的方法大多都是手动编辑/etc/apt/source.list,其实有更方便的做法。打开新立得包管理器,在设置里的软件库中选择下载源即可,建议同时取消勾选other software中的CD/DVD源。

2. 安装 sudo

输入 su 切换到root,安装sudo后,添加个人用户到sudo组:adduser xxx sudo 然后注销重新登录,sudo即可用。不需要手动编辑sudo配置文件。

3. Xfce 调整双击间隔

默认Xfce窗口是支持双击标题栏最大化最小化窗口的,但是默认安装后基本感觉没有效果,这是因为默认双击间隔是250ms,太短,在设置里的鼠标中调整双击阈值为400,即可。

 

待补充...

虚拟机socket通信丢失头字节奇怪问题一枚

问题描述:在虚拟机里的Linux上用socket TCP (C 编写)连接 Win 主机上 socket(python 编写) 服务器,获取的数据经常少一个字节,而且都是数据的头字节。使用 telnet 连接也是如此。在 Win 主机上用 Socket 调试工具和telnet 都是正常,不会丢失。

硬件环境:虚拟机为 Orcale VM VritualBox 4.1.2,虚拟机上系统为 Debian 6 x86-x64,虚拟机网络类型为 NAT。主机系统为 WinXP SP3 x86。

虚拟机linux下代码:

#include    "unp.h"

int
main(int argc, char **argv)
{
    int    sockfd, n;
    char    recvline[MAXLINE + 1];
    struct sockaddr_in    servaddr;

    if (argc != 2)
        err_quit("usage: a.out <IPaddress>");

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port   = htons(4013);    /* daytime server */
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
        err_quit("inet_pton error for %s", argv[1]);

    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
        err_sys("connect error");

    while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
        recvline[n] = 0;    /* null terminate */
        printf("%d read from the socket\n", n);
        if (fputs(recvline, stdout) == EOF)
            err_sys("fputs error");
    }
    if (n < 0)
        err_sys("read error");

    exit(0);
}

这代码其实就是《UNIX 网络编程卷1》(UNP)中的第一个程序( unpv13e/intro/daytimetcpcli.c ),用 tcp 连接服务器,读取时间信息的。上述代码做了微小改动。UNP的第三版代码 unpv13e 可以在这里这里下载。

为了测试这个代码我在 Win 主机上用 python 写了一个服务程序:

import socket
import time

host = '192.168.1.68'
port = 4013

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(5)

while True:
    connection, address = s.accept()
    t = time.strftime("%a %X %x", time.localtime()).encode("ascii")
    c = connection.send(t)
    print("{0:d} sent of {1:d}: ".format(c, len(t)), "\"{0}\"".format(t.decode("ascii")), "TO client {0[0]}:{0[1]}".format(address))
    connection.close()

其中 192.168.1.68 是主机在局域网中的地址,绑定到这个地址上虚拟机中程序也可以访问到服务器。

当在虚拟机中用编译好的程序或者 telnet 访问 Win 上服务器时,经常会输出如下

"ri 16:22:52 12/28/12"

少了头部一个字符 "F" ,读取只是20个字节,但是也有时候正常,但是正常的几率低于 40%(目测)。

而在 Win 主机上打印输出都是正常的,'21 sent of 21:  "Fri 16:54:40 12/28/12" TO client 192.168.1.68:18289' 这样的,的确都是把 21 个字节发送完毕。

在 Win 主机上用 telnet 或者 TCP/UDP socket 调试助手来测试,获取的数据也都正常,为21字节,没有丢失头字节的情况发生。

(⊙﹏⊙) 

感觉可能是虚拟机 NAT 模式的问题或者还是什么,但是只丢失头字节的确是好奇怪。。。。

·-·-·-·-·-·--·-·-· 2012-12-29 分割线 -·-·-·-·-·-·-·-·--·-·-·-·

今天又测试了下,这次通信获取数据大部分情况下是正常的,只有约10%的几率会丢失头字节。在虚拟机里装了tcpdump 工具来看看情况。

两次通信

tisyang@debian:~/Sources/unpv13e/intro$ ./daytimetcpcli 192.168.1.68
20 read from the socket
at 09:14:47 12/29/12

tisyang@debian:~/Sources/unpv13e/intro$ ./daytimetcpcli 192.168.1.68
21 read from the socket
Sat 09:14:51 12/29/12

说明第一次通信丢失了头字节 'S',第二次通信正常。在此同时,我已经运行 tcpdump 来截获和主机 192.168.1.68 的通信包,命令和输出如下

tisyang@debian:~$ sudo tcpdump  host 192.168.1.68
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

09:14:46.337897 IP 10.0.2.15.43314 > 192.168.1.68.4013: Flags [S], seq 3451477296, win 14600, options [mss 1460,sackOK,TS val 398218 ecr 0,nop,wscale 6], length 0
09:14:46.341664 IP 192.168.1.68.4013 > 10.0.2.15.43314: Flags [S.], seq 46272001, ack 3451477297, win 65535, options [mss 1460], length 0
09:14:46.341712 IP 10.0.2.15.43314 > 192.168.1.68.4013: Flags [.], ack 1, win 14600, length 0
09:14:46.341747 IP 192.168.1.68.4013 > 10.0.2.15.43314: Flags [S.], seq 46272001, ack 3451477297, win 65535, options [mss 1460], length 0
09:14:46.341837 IP 10.0.2.15.43314 > 192.168.1.68.4013: Flags [.], ack 1, win 14600, length 0
09:14:46.341865 IP 192.168.1.68.4013 > 10.0.2.15.43314: Flags [FP.], seq 1:21, ack 1, win 65535, length 20
09:14:46.342276 IP 10.0.2.15.43314 > 192.168.1.68.4013: Flags [F.], seq 1, ack 22, win 14600, length 0
09:14:46.342360 IP 192.168.1.68.4013 > 10.0.2.15.43314: Flags [.], ack 2, win 65535, length 0


09:14:49.632861 IP 10.0.2.15.43315 > 192.168.1.68.4013: Flags [S], seq 3496530236, win 14600, options [mss 1460,sackOK,TS val 399041 ecr 0,nop,wscale 6], length 0
09:14:49.633743 IP 192.168.1.68.4013 > 10.0.2.15.43315: Flags [S.], seq 46720001, ack 3496530237, win 65535, options [mss 1460], length 0
09:14:49.633771 IP 10.0.2.15.43315 > 192.168.1.68.4013: Flags [.], ack 1, win 14600, length 0
09:14:49.633983 IP 192.168.1.68.4013 > 10.0.2.15.43315: Flags [P.], seq 1:22, ack 1, win 65535, length 21
09:14:49.634048 IP 192.168.1.68.4013 > 10.0.2.15.43315: Flags [F.], seq 22, ack 1, win 65535, length 0
09:14:49.634245 IP 10.0.2.15.43315 > 192.168.1.68.4013: Flags [.], ack 22, win 14600, length 0
09:14:49.634749 IP 10.0.2.15.43315 > 192.168.1.68.4013: Flags [F.], seq 1, ack 23, win 14600, length 0
09:14:49.634815 IP 192.168.1.68.4013 > 10.0.2.15.43315: Flags [.], ack 2, win 65535, length 0

输出中的分段是我添加的,为了区分第一次通信和第二次通信。显然,第一次通信中就只获取到了 20 个字节(length 20),而第二次正常(length 21)。

TCP 连接要经过3次握手,而关闭需要4次握手,从第二次通信就可以看出来。

而在第一次通信中,3次握手tcp建立后,服务器很奇怪的发来一个 SYN 包,而且 FIN 包(用于连接终止)和 PUSH 包(传送数据)是在同一个包内。而在第二次通信里,没有这种情况。

 

使用 Github 中

Git 是个好东西,至少给我的感觉是超级棒的。

最近刚看完了『Unix编程艺术』,感触良多,说实话,这本书值得所有程序猿去看的,虽然讲的是Unix哲学,其实我感觉,对于Windows下的程序猿来讲,这本书里讲了太多值得他们去学习的东西。

最近也开始学习Git了,也在自己的Github帐号上建了几个仓库。恰巧前两天弄出个脚本,用来KDE环境下命令行删除文件到回收站的,比起恐怖的RM命令来说,是个很好的用品。于是就建了一个shell 脚本的仓库,给move2trash脚本上添加了点注释,就提交上来了。不过话说,我的英文真的好烂好烂。。。。。。。

给个链接:

https://github.com/tisyang/shell-script/blob/master/kde-script/move2trash

 

目前来说,Git还是不大熟悉,继续努力吧。

KDE 命令行删除文件到回收站脚本

 

#!/bin/bash
for fileName in "$@"
do
    if [ ! -e $fileName ];then
        echo "****  $fileName  NOT existed!"
        exit
    fi
    kioclient move "$fileName" trash:/ 2> /dev/null && echo "----  trashed:   $fileName"
done

经过测试,暂时没有什么问题,我的环境是 Debian 6.0 KDE。 这个脚本仅限KDE环境。
可以把这个脚本丢到 /usr/local/bin/ 下,作为常用命令使用,不要忘了赋予执行权限。

 

I hate dotnet and ms

 

最近在看Unix 编程艺术,其实也是当休闲书籍看来着。
不过有很多感触,对于书里提出的很多原则和方法。
比如线程的问题。
 
    linux 里没有等同于windows下的源生线程的东西,使用的是轻量级用户进程。线程的问题在于,多线程之间共享了过多的东西,这种共享是硬性的,默认的,容易引发问题,典型的就是C库的全局变量冲突问题,所以win下有包装过的多线程C库和单线程C库。而多进程的模型中,进程彼此的C库是独立的,其他资源默认也会是独立的,不会互相冲突,对于需要共享的资源只要通过灵活的IPC机制传递或者共享文件描述符。线程间的资源是默认共享,而进程间的资源是默认独立的,前者暴露了太多细节。就并发性来说,两者应该没有太多性能上的区别,轻量级线程的切换和线程切换,性能上现在也差别不是很大了。
 
自己还是对.net 执有偏见,或者说有些抵触的态度,我的感觉是,MS 的开发链变迁真的让开发人员心憔力悴,虽然很多的windows开发者并没有这种感觉,也不会认可这种感觉。MS 我个人觉得苦逼的程序猿大多是win下吧,唉。Unix的简单哲学,KISS原则,真的很适合让自己去反省和深思的。
还有一些就是关于设计模式和Ruby了。虽然自己对于设计模式也是懂的很浅的,不过不应该把设计模式的思想仅仅拘泥在面向对象的语言中,再进一步说,不应该把设计模式的一些思想拘泥在面向对象之中,这是从这本书里感悟到的。
 
虽然从emacs奔向了vim,但是最终还是镇守在ruby这边,没有逃向python。原因感觉也不清楚。相对来说,我不喜欢那种极度严谨的感觉。国内的ruby 真的不活跃。仅有的活跃地方应该是 Ror 和 RGSS了,我也是个初学者,也需要努力的。