用人之道

  古文:用人之道

  太宗令封德彝举贤,久无所举。上诘之,对曰:“非不尽心,但于今未有奇才耳!”上曰:“君子用人如器,各取所长。古之致治者,岂借才于异代乎?正患己不能知,安可诬一世之人!”
  注释:
  ⑴上:即唐太宗李世民 ⑵诘:责备 ⑶器:器皿,器具。 ⑷致治:治理好国家(5)代:朝代. (6)封德彝:名伦,太宗手下的官员
  译:
  唐太宗让封德彝举荐有才能的人,他过了好久也没有推荐一个人。太宗责问他,他回答说:“不是我不尽心去做,只是当今没有杰出的人才啊!”太宗说:“用人跟用器物一样,每一种东西都要选用它的长处。古来能使国家达到大治的帝王,难道是向别的朝代去借人才来用的吗?我们只是担心自己不能识人,怎么可以冤枉当今一世的人呢?”
  道理:要知人善用。

曹操的五个用人之道

  曹操的五个用人之道:
  曹操的用人政策一: 名至实归 更重实际;
  曹操的用人政策二: 德才兼备 唯才是举;
  曹操的用人政策三: 重用清官 不避小贪;
  曹操的用人政策四: 招降纳叛 尽释前嫌;
  曹操的用人政策五: 抓大放小 不拘小节

诸葛亮的用人之道

  诸葛亮当权期间,反刘备依靠大族的政策,开始实行法治,大力打击益洲派的豪强;由于川中战乱没中原那严重,加上刘焉父子纵容大族,所以豪强势力还是十分强大,收益不错但是为后来的李严不供粮草埋下伏笔。诸葛亮很善于发现、培养、利用人才,如蒋琬、费文伟、董允等,诸葛亮的识人方面,杨洪、何诋的例子一直为后人所乐道;诸葛亮也注意提拔敌方投降过来的人才,如姜维、王平。诸葛亮大力起用荆洲派人才,在选拔人才和使用人才方面过分强调以“奉职循理”作为衡量优劣、取舍的标准,因而忽略了人才的多样性,尤其是开拓型人才的培养和造就。如街亭用的马谡、四相中的蒋琬、费文伟、董允都是荆洲派。
  由于诸葛亮的人才政策局限,加上刘蜀中生代人才大部分在夷陵之战中消亡,无奈后来只好“蜀中无大将,廖化当先锋”的悲惨局面。

刘邦的用人之道

  《史记高祖本纪》载, 上(刘邦)问曰:“如我能将几何?”信(韩信)曰:“陛下不过能将十万。”上曰:“于君如何?”信曰:“臣多多而益善耳。”上笑曰:“多多益善,何为我禽?”信曰:“陛下不能将兵,而善将将,此乃信之所以为陛下禽也。”
  刘邦在用人方面确实有他独到的地方,在谋略方面,他比不上张良、陈平;在打仗方面,他比不上韩信、彭越;在治理国家上,他不及萧何。然而,刘邦能够最大限度地使用人才,知道把手下的人才放在最合适的位置,这就是刘邦的用人之道,其精妙之处,究竟在什么地方呢?
  刘邦的用人之道
  一:知人善任
  二:不拘一格
  三:不计前嫌
  四:坦诚相待
  五:用人不疑
  六:论功行赏

唐太宗的用人之道

  唐太宗李世民是中国古代历史上最为贤明的皇帝之一,他的很多治国之道久为后世所推崇,即便放在今天仍值得我们认真借鉴学习。而在他的所有治国方略中,用人之道又更为重要。
  唐太宗喜欢人才,也擅长用人,在他理政的23年时间里,所用的文臣武将不胜枚举,著名点的有魏征、尉迟敬德、房玄龄、杜如晦等。纵观太宗用人之道,可以归纳为以下几点:
  首先,重视人才,太宗认为“能安天下者,惟在用得人才”。当年太宗平定刘周武,刘下属部将虽然投降,但随后又纷纷叛逃而去,只剩尉迟敬德还留在营中。太宗手下诸将劝他杀了敬得,免生后患,但太宗却认为敬德是个人才,不仅不杀反而重用之。后来敬德果然屡立战功,甚至还救了太宗一命;
  其次,知人善用。太宗命封德彝举荐人才,封领命很久都没有举荐一个。太宗问他为何,他说:“不是我不尽心,而是现在没有旷世奇才。”太宗责备他说:“人的才能,各有所长,君子用人,就如同用器皿一样,大才大用,小才小用,各取所长。”
  第三,对人推心置腹,以诚相待。有人给太宗出主意,要太宗采用些计谋或权术来试探朝中大臣的忠奸。太宗回答说:“如果用这些权术去试探部下,自身就不够光明磊落,如何要求他们正直呢?”张居正对此的评论也非常深刻:“君德贵明不贵察,明生于诚,其效至于不忍欺,察生于疑,其弊至于无所容,盖其相去远矣。”
  最后,有容人之量。太宗在位,时常有大臣秉理直谏,而太宗却常能接受各种不同意见,从不固执己见,也不偏听偏信。张居正更是认为太宗能够兼听为明主要是他虚心求教的结果,这也正是孔夫子“敏而好学,不耻下问”所要达到的境界。

摘自: http://baike.baidu.com/view/1384826.htm

linux kernel 2.4.5 ipv4 socket层的一点解释

1.新建socket
函数原形:
static int inet_create(struct socket *sock, int protocol)
在net/ipv4/af_inet.c中
详细解释

static int inet_create(struct socket *sockint protocol

struct sock *sk

struct proto *prot

sock->state SS_UNCONNECTED; 
/* 设置状态为未连接 */ 
sk sk_alloc(PF_INETGFP_KERNEL1); 
/* 申请sock所需的内存 */ 
   
/* net/core/sock.c */ 
if (sk == NULL

 goto do_oom

switch (
sock->type
) { 
case 
SOCK_STREAM:  
/* TCP协议 */ 
 if (protocol && protocol != IPPROTO_TCP

  goto free_and_noproto

 protocol IPPROTO_TCP

 prot = &tcp_prot; 
/* tcp_prot定义在net/ipv4/tcp_ipv4.c */ 
 sock->ops = &inet_stream_ops
/* 针对STREAM的socket操作 */ 
 break

case 
SOCK_SEQPACKET:  
/* 不支持 */ 
 goto free_and_badtype

case 
SOCK_DGRAM:  
/* UDP协议 */ 
 if (protocol && protocol != IPPROTO_UDP

  goto free_and_noproto

 protocol IPPROTO_UDP

 sk->no_check UDP_CSUM_DEFAULT

 prot=&udp_prot;  
/* udp_prot定义在net/ipv4/udp.c */ 
 sock->ops = &inet_dgram_ops
/* 针对DGRAM的socket操作 */ 
 break

case 
SOCK_RAW:  
/* RAW */ 
 if (!capable(CAP_NET_RAW)) 
/* 判断是否有权利建立SOCK_RAW */ 
  goto free_and_badperm

 if (!protocol)  
/* protocol不能为0 */ 
  goto free_and_noproto

 prot = &raw_prot; 
/* raw_prot定义在net/ipv4/raw.c */ 
 sk->reuse 1;  
/* 允许地址重用 */ 
 sk->num protocol

 sock->ops = &inet_dgram_ops
/* RAW的一些特性和DGRAM相同 */ 
 if (protocol == IPPROTO_RAW

  sk->protinfo.af_inet.hdrincl 1

   
/* 允许自己定制ip头 */ 
 break

default: 
 goto free_and_badtype


if (
ipv4_config.no_pmtu_disc

 sk->protinfo.af_inet.pmtudisc IP_PMTUDISC_DONT

else 
 sk->protinfo.af_inet.pmtudisc IP_PMTUDISC_WANT

sk->protinfo.af_inet.id 0

sock_init_data(sock,sk); 
/* 初始化一些数据 */ 
   
/* net/core/sock.c */ 
sk->destruct inet_sock_destruct
/* 当销毁socket时调用inet_sock_destruct */ 
sk->zapped 0

sk->family PF_INET

sk->protocol protocol

sk->prot prot

sk->backlog_rcv prot->backlog_rcv
/* prot->backlog_rcv()见各个类型的定义 */ 
sk->protinfo.af_inet.ttl sysctl_ip_default_ttl
/* 设置默认ttl */ 
   
/* 修改/proc/sys/net/ipv4/ip_default_ttl */ 
sk->protinfo.af_inet.mc_loop 1

sk->protinfo.af_inet.mc_ttl 1

sk->protinfo.af_inet.mc_index 0

sk->protinfo.af_inet.mc_list NULL

#ifdef INET_REFCNT_DEBUG 
atomic_inc(&inet_sock_nr
); 
#endif 
if (sk->num
) { 
 
/* It assumes that any protocol which allows 
  * the user to assign a number at socket 
  * creation time automatically 
  * shares. 
  */ 
 sk->sport htons(sk->num); 
/* 设置本地端口 */ 
 
/* Add to protocol hash chains. */ 
 sk->prot->hash(sk
); 

if (
sk->prot->init
) { 
 int err sk->prot->init(sk); 
/* 协议对socket的初始化 */ 
 if (err != 0
) { 
  inet_sock_release(sk
); 
  return(err
); 
 


return(
0
); 
free_and_badtype

sk_free(sk);  
/* 释放内存 */ 
return –ESOCKTNOSUPPORT

free_and_badperm

sk_free(sk
); 
return –
EPERM

free_and_noproto

sk_free(sk
); 
return –
EPROTONOSUPPORT

do_oom

return –
ENOBUFS


在net/core/sock.

void sock_init_data
(struct socket *sockstruct sock *sk


skb_queue_head_init(&sk->receive_queue); 
/* 初始化3条队列 接受,发送,错误*/ 
skb_queue_head_init(&sk->write_queue
); 
skb_queue_head_init(&sk->error_queue
); 
init_timer(&sk->timer);  
/* 初始化timer */ 

sk->allocation GFP_KERNEL
sk->rcvbuf sysctl_rmem_default

sk->sndbuf sysctl_wmem_default

sk->state = TCP_CLOSE

sk->zapped 1

sk->socket sock

if(
sock


 sk->type sock->type

 sk->sleep = &sock->wait

 sock->sk sk

} else 
 sk->sleep NULL

sk->dst_lock RW_LOCK_UNLOCKED

sk->callback_lock RW_LOCK_UNLOCKED

   
/* sock_def_wakeup(),sock_def_readable(), 
    sock_def_write_space(),sock_def_error_report(), 
    sock_def_destruct() 在net/core/sock.c */ 
sk->state_change sock_def_wakeup

sk->data_ready sock_def_readable

sk->write_space sock_def_write_space

sk->error_report sock_def_error_report

sk->destruct      =    sock_def_destruct

sk->peercred.pid 0

sk->peercred.uid = –1

sk->peercred.gid = –1

sk->rcvlowat 1

sk->rcvtimeo MAX_SCHEDULE_TIMEOUT
/* 设置接受,发送超时 */ 
sk->sndtimeo MAX_SCHEDULE_TIMEOUT

atomic_set(&sk->refcnt1
); 

1.1 SOCK_STREAM的初始化 
在net
/ipv4/tcp_ipv4.

static int tcp_v4_init_sock(struct sock *sk


struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp
); 
skb_queue_head_init(&tp->out_of_order_queue
); 
tcp_init_xmit_timers(sk
); 
tcp_prequeue_init(tp
); 
tp->rto TCP_TIMEOUT_INIT

tp->mdev TCP_TIMEOUT_INIT

    
/* So many TCP implementations out there (incorrectly) count the 
 * initial SYN frame in their delayed-ACK and congestion control 
 * algorithms that we must have the following bandaid to talk 
 * efficiently to them. -DaveM 
 */ 
tp->snd_cwnd 2

/* See draft-stevens-tcpca-spec-01 for discussion of the 
 * initialization of these values. 
 */ 
tp->snd_ssthresh 0x7fffffff
/* Infinity */ 
tp->snd_cwnd_clamp = ~0

tp->mss_cache 536

tp->reordering sysctl_tcp_reordering

sk->state TCP_CLOSE

sk->write_space tcp_write_space
/* tcp_write_space() 在net/ipv4/tcp.c */ 
sk->use_write_queue 1

sk->tp_pinfo.af_tcp.af_specific = &ipv4_specific

   
/* ipv4_specific 在net/ipv4/tcp_ipv4.c */ 
sk->sndbuf sysctl_tcp_wmem[1]; 
/* 设置发送和接收缓冲区大小 */ 
sk->rcvbuf sysctl_tcp_rmem[1]; 
/* sysctl_tcp_* 在net/ipv4/tcp.c */ 
atomic_inc(&tcp_sockets_allocated); 
/* tcp_sockets_allocated是当前TCP socket的数量 */ 
return 0

}

SOCK_DGRAM无初始化
1.2 SOCK_RAW初始化
在net/ipv4/raw.c

static int raw_init(struct sock *sk

struct raw_opt *tp = &(sk->tp_pinfo.tp_raw4
); 
if (
sk->num == IPPROTO_ICMP

 memset(&tp->filter0sizeof(tp->filter
)); 
return 
0

}

2.Server
2.1 bind

static int inet_bind(struct socket *sockstruct sockaddr *uaddrint addr_len

struct sockaddr_in *addr=(struct sockaddr_in *)uaddr

struct sock *sk=sock->sk

unsigned short snum

int chk_addr_ret

int err

/* If the socket has its own bind function then use it. (RAW) */ 
if(sk->prot->bind

 return sk->prot->bind(skuaddraddr_len
); 
    
/* 只有SOCK_RAW定义了自己的bind函数 */ 
if (addr_len sizeof(struct sockaddr_in
)) 
 return EINVAL

chk_addr_ret inet_addr_type(addr->sin_addr.s_addr
); 
    
/* inet_addr_type返回地址的类型 */ 
    
/* 在net/ipv4/fib_frontend.c */ 
/* Not specified by any standard per-se, however it breaks too 
 * many applications when removed. It is unfortunate since 
 * allowing applications to make a non-local bind solves 
 * several problems with systems using dynamic addressing. 
 * (ie. your servers still start up even if your ISDN link 
 * is temporarily down) 
 */ 
if (sysctl_ip_nonlocal_bind == 
&& 
   sk->protinfo.af_inet.freebind == 
&& 
   addr->sin_addr.s_addr != INADDR_ANY 
&& 
   chk_addr_ret != RTN_LOCAL 
&& 
   chk_addr_ret != RTN_MULTICAST 
&& 
   chk_addr_ret != RTN_BROADCAST

 return EADDRNOTAVAIL

snum ntohs(addr->sin_port
); 
if (
snum && snum PROT_SOCK && !capable(CAP_NET_BIND_SERVICE
)) 
   
/* 检查是否有权利bind端口到1-1024 */ 
 return EACCES

/*   We keep a pair of addresses. rcv_saddr is the one 
 *   used by hash lookups, and saddr is used for transmit. 
 * 
 *   In the BSD API these are the same except where it 
 *   would be illegal to use them (multicast/broadcast) in 
 *   which case the sending device address is used. 
 */ 
lock_sock(sk
); 
/* Check these errors (active socket, double bind). */ 
err = –EINVAL

if ((
sk->state != TCP_CLOSE)  
|| 
   (sk->num != 0
)) 
 goto out

sk->rcv_saddr sk->saddr addr->sin_addr.s_addr

if (
chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST

 sk->saddr 0; 
/* Use device */ 
/* Make sure we are allowed to bind here. */ 
if (sk->prot->get_port(sksnum) != 0) { 
/* get_port检查是否重用 */ 
 sk->saddr sk->rcv_saddr 0

 err = –EADDRINUSE

 goto out


if (
sk->rcv_saddr

 sk->userlocks |= SOCK_BINDADDR_LOCK

if (
snum

 sk->userlocks |= SOCK_BINDPORT_LOCK

sk->sport htons(sk->num
); 
sk->daddr 0

sk->dport 0

sk_dst_reset(sk
); 
err 0

out

release_sock(sk
); 
return 
err

SOCK_STREAM和SOCK_DGRAM用默认的bind
2.1.1 SOCK_RAW的bind
在net/ipv4/raw.c

static int raw_bind(struct sock *skstruct sockaddr *uaddrint addr_len

struct sockaddr_in *addr = (struct sockaddr_in *) uaddr

int ret = –EINVAL

int chk_addr_ret

if (
sk->state != TCP_CLOSE || addr_len sizeof(struct sockaddr_in
)) 
 goto out

chk_addr_ret inet_addr_type(addr->sin_addr.s_addr
); 
    
/* inet_addr_type返回地址的类型 */ 
    
/* 在net/ipv4/fib_frontend.c */ 
ret = –EADDRNOTAVAIL

if (
addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL 
&& 
   chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST

 goto out

sk->rcv_saddr sk->saddr addr->sin_addr.s_addr

    
/* sk->rcv_saddr 捆绑的本地地址 */ 
    
/* sk->saddr 源地址 */ 
if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST

 sk->saddr 0; 
/* Use device */ /* 地址类型如为多播或是广播源地址为0 */ 
sk_dst_reset(sk
); 
ret 0

out: return ret


2.2 listen
2.2.1 SOCK_STREAM的listen
在net/ipv4/af_inet.c

int inet_listen(struct socket *sockint backlog

struct sock *sk sock->sk

unsigned char old_state

int err

lock_sock(sk
); 
err = –EINVAL

if (
sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM

 goto out

old_state sk->state

if (!((
1<<old_state)&(TCPF_CLOSE|TCPF_LISTEN
))) 
 goto out

/* Really, if the socket is already in listen state 
 * we can only allow the backlog to be adjusted. 
 */ 
if (old_state != TCP_LISTEN
) { 
 err tcp_listen_start(sk); 
/* 真正实现TCP协议listen */ 
 if (err

  goto out


sk->max_ack_backlog backlog

err 0

out

release_sock(sk
); 
return 
err


//tcp_listen_start在net/ipv4/tcp.h 
int tcp_listen_start(struct sock *sk


struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp
); 
struct tcp_listen_opt *lopt

sk->max_ack_backlog 0

sk->ack_backlog 0

tp->accept_queue tp->accept_queue_tail NULL

tp->syn_wait_lock RW_LOCK_UNLOCKED

tcp_delack_init(tp);  
/* tp清0 */ 
   
/* include/net/tcp.h */ 
lopt kmalloc(sizeof(struct tcp_listen_opt), GFP_KERNEL
); 
if (!
lopt

 return ENOMEM

memset(lopt0sizeof(struct tcp_listen_opt
)); 
for (
lopt->max_qlen_log 6; ; lopt->max_qlen_log
++) 
 if ((1<<lopt->max_qlen_log) >= sysctl_max_syn_backlog

  
break; 
write_lock_bh(&tp->syn_wait_lock
); 
tp->listen_opt lopt

write_unlock_bh(&tp->syn_wait_lock
); 
/* There is race window here: we announce ourselves listening, 
 * but this transition is still not validated by get_port(). 
 * It is OK, because this socket enters to hash table only 
 * after validation is complete. 
 */ 
sk->state TCP_LISTEN

if (
sk->prot->get_port(sksk->num) == 0) { 
/* 确认地址没有重用 */ 
 sk->sport htons(sk->num); 
/* 设置源端口 */ 
 sk_dst_reset(sk
); 
 sk->prot->hash(sk);  
/* 将端口加到hash表中 */ 
 return 0


sk->state TCP_CLOSE

write_lock_bh(&tp->syn_wait_lock
); 
tp->listen_opt NULL

write_unlock_bh(&tp->syn_wait_lock
); 
kfree(lopt
); 
return –
EADDRINUSE


SOCK_DGRAM 和 SOCK_RAW 不支持listen
2.3 accept
2.3.1 SOCK_STREAM的accept
在net/ipv4/af_inet.c

int inet_accept(struct socket *sockstruct socket *newsockint flags

struct sock *sk1 sock->sk

struct sock *sk2

int err = –EINVAL

if((
sk2 sk1->prot->accept(sk1,flags,&err)) == NULL

 goto do_err

lock_sock(sk2
); 
BUG_TRAP((1<<sk2->state)&(TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_CLOSE
)); 
sock_graft(sk2newsock); 
/* 将sk2转接到newsock */ 
   
/* 在include/net/sock.h */ 
newsock->state SS_CONNECTED

release_sock(sk2
); 
return 
0

do_err

return 
err


SOCK_DGRAM 和 SOCK_RAW 不支持 accept
2.3.1.1 TCP协议的accept
在net/ipv4/tcp.c

struct sock *tcp_accept(struct sock *skint flagsint *err

struct tcp_opt *tp = &sk->tp_pinfo.af_tcp

struct open_request *req

struct sock *newsk

int error

lock_sock(sk
); 
/* We need to make sure that this socket is listening, 
 * and that it has something pending. 
 */ 
error = –EINVAL

if (
sk->state != TCP_LISTEN) 
/* 检查socket是否处于listen状态 */ 
 goto out

/* Find already established connection */ 
if (!tp->accept_queue) { 
/* 判断accept队列是否准备好 */ 
 long timeo sock_rcvtimeo(skflags O_NONBLOCK
); 
   
/* 判断是否为堵塞模式 */ 
   
/* 在include/net/sock.h */ 
 
/* If this is a non blocking socket don’t sleep */ 
 error = –EAGAIN

 if (!timeo)  
/* 不堵塞模式,直接返回 */ 
  goto out

 error wait_for_connect(sktimeo); 
/* 进入空闲等待连接 */ 
 if (error

  goto out


req tp->accept_queue

if ((
tp->accept_queue req->dl_next) == NULL

 tp->accept_queue_tail NULL

 newsk req->sk

tcp_acceptq_removed(sk);  
/* sk当前连接数减1 */ 
    
/*在include/net/tcp.h */ 
tcp_openreq_fastfree(req);  
/* 释放内存 */ 
    
/*在include/net/tcp.h */ 
BUG_TRAP(newsk->state != TCP_SYN_RECV);
  
release_sock
(sk
); 
return 
newsk

out

release_sock(sk
); 
*
err error

return 
NULL


/* 只有当socket为堵塞模式,该函数才会被调用 */ 
/* 在net/ipv4/tcp.c */ 
static int wait_for_connect(struct sock sklong timeo


DECLARE_WAITQUEUE(waitcurrent
); 
int err

/* 
 * True wake-one mechanism for incoming connections: only 
 * one process gets woken up, not the ‘whole herd’. 
 * Since we do not ‘race & poll’ for established sockets 
 * anymore, the common case will execute the loop only once. 
 * 
 * Subtle issue: "add_wait_queue_exclusive()" will be added 
 * after any current non-exclusive waiters, and we know that 
 * it will always _stay_ after any new non-exclusive waiters 
 * because all non-exclusive waiters are added at the 
 * beginning of the wait-queue. As such, it’s ok to "drop" 
 * our exclusiveness temporarily when we get woken up without 
 * having to remove and re-insert us on the wait queue. 
 */ 
add_wait_queue_exclusive(sk->sleep, &wait
); 
for (;;) { 
 current->state TASK_INTERRUPTIBLE

 release_sock(sk
); 
 if (sk->tp_pinfo.af_tcp.accept_queue == NULL

  timeo schedule_timeout(timeo); 
/* 休眠timeo时长 */ 
 lock_sock(sk
); 
 err 0

 if (sk->tp_pinfo.af_tcp.accept_queue) 
/* accept队列可用 */ 
    
/* 也就是有连接进入 */ 
  
break; 
 err = –EINVAL

 if (sk->state != TCP_LISTEN

  
break; 
 err sock_intr_errno(timeo
); 
 if (signal_pending(current
)) 
  
break; 
 err = –EAGAIN

 if (!timeo

  
break; 

current->state TASK_RUNNING

remove_wait_queue(sk->sleep, &wait
); 
return 
err


3.Client
3.1 connect
3.1.1 SOCK_STREAM的connect
在net/ipv4/af_inet.c

int inet_stream_connect(struct socket *sockstruct sockaddr uaddr
  int addr_lenint flags


struct sock *sk=sock->sk

int err

long timeo

lock_sock(sk
); 
if (
uaddr->sa_family == AF_UNSPEC
) { 
 err sk->prot->disconnect(skflags); 
/* 关闭连接 */ 
 sock->state err SS_DISCONNECTING SS_UNCONNECTED

 goto out


switch (
sock->state
) { 
default: 
 err = –EINVAL

 goto out

case 
SS_CONNECTED

 err = –EISCONN

 goto out

case 
SS_CONNECTING

 err = –EALREADY

 
/* Fall out of switch with err, set for this state */ 
 break

case 
SS_UNCONNECTED

 err = –EISCONN

 if (sk->state != TCP_CLOSE

  goto out

 err = –EAGAIN

 if (sk->num == 0
) { 
  if (sk->prot->get_port(sk0) != 0
/* 是否重用 */ 
  goto out

  sk->sport htons(sk->num
); 
 

 err sk->prot->connect(skuaddraddr_len); 
/* 调用协议的connect */ 
 if (err 0

  goto out

  sock->state SS_CONNECTING;  
/* socket状态设置成连接中 */ 
 
/* Just entered SS_CONNECTING state; the only 
  * difference is that return value in non-blocking 
  * case is EINPROGRESS, rather than EALREADY. 
  */ 
 err = –EINPROGRESS

 break


timeo sock_sndtimeo(skflags&O_NONBLOCK); 
/* 是否为堵塞模式 */ 
    
/* 在include/net/sock.h */ 
if ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) { 
/* 连接为完成 */ 
 
/* Error code is set above */ 
 if (!timeo || !inet_wait_for_connect(sktimeo
)) 
    
/* 非堵塞模式立即返回 */ 
    
/* 堵塞模式调用inet_wait_for_connect() */ 
  goto out

 err sock_intr_errno(timeo
); 
 if (signal_pending(current
)) 
  goto out


/* Connection was closed by RST, timeout, ICMP error 
 * or another process disconnected us. 
 */ 
if (sk->state == TCP_CLOSE

 goto sock_error

/* sk->err may be not zero now, if RECVERR was ordered by user 
 * and error was received after socket entered established state. 
 * Hence, it is handled normally after connect() return successfully. 
 */ 
sock->state SS_CONNECTED;  
/* 设置状态为已连接 */ 
err 0

out

release_sock(sk
); 
return 
err

sock_error

err sock_error(sk) ? : –ECONNABORTED

sock->state SS_UNCONNECTED

if (
sk->prot->disconnect(skflags
)) 
 sock->state SS_DISCONNECTING

goto out


/* 只有当socket为堵塞模式,该函数才会被调用 */ 
/* 在/net/ipv4/af_inet.c */ 
static long inet_wait_for_connect(struct sock *sklong timeo


DECLARE_WAITQUEUE(waitcurrent
); 
__set_current_state(TASK_INTERRUPTIBLE
); 
add_wait_queue(sk->sleep, &wait
); 
/* Basic assumption: if someone sets sk->err, he _must_ 
 * change state of the socket from TCP_SYN_*. 
 * Connect() does not allow to get error notifications 
 * without closing the socket. 
 */ 
while ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV
)) { 
 release_sock(sk
); 
 timeo schedule_timeout(timeo); 
/* 进入休眠 */ 
 lock_sock(sk
); 
 if (signal_pending(current) || !timeo

  
break; 
 set_current_state(TASK_INTERRUPTIBLE
); 

__set_current_state(TASK_RUNNING
); 
remove_wait_queue(sk->sleep, &wait
); 
return 
timeo


摘自: http://www.infosecurity.org.cn/article/hacker/tutor/12424.html

清明节

清明节

目录
【清明节起源】
寒食节
【25个民族过清明节】
【清明节由来】
【清明节习俗】

【清明节起源】

  Ching Ming Festival; Tomb-sweeping Festival

  

 清明节是我国民间重要的传统节日,是重要的“八节”(上元又名元宵节、清明、立夏、端午、中元、中秋、冬至和除夕)之一。一般是在公历的四月五日,但其节期很长,有十日前八日后及十日前十日后两种说法,这近二十天内均属清明节。 清明节的起源,据传始于古代帝王将相“墓祭”之礼,后来民间亦相仿效,于此日祭祖扫墓,历代沿袭而成为中华民族一种固定的风俗。

  清明节源于商代时代,是我国汉族的传统节日之一,为中国二十四节气之一,时间约在每年的阳历4月5日前后。清明节后雨水增多,大地呈现春和景明之象。这一时节万物“吐故纳新”,无论是大自然中的植被,还是与自然共处的人体,都在此时换去冬天的污浊,迎来春天的气息,实现由阴到阳的转化。

  古有清明前一天为“寒食节”之说,相传起于春秋时期晋文公悼念介子推“割股充饥”一事,后逐渐清明寒食合二为一。唐代扫墓日期一般在寒食节,宋后移到清明。传说中“寒食节”的起源地就在山西中部介休,介休一名的来历即是为纪念介子推“割股充饥”而不图为报,最终在此被大火烧山而亡,绵山也因此又称“介山”。

  相传大禹治水后,人们就用“清明”之语庆贺水患已除,天下太平。此时春暖花开,万物复苏,天清地明,正是春游踏青的好时节。踏青早在唐代就已开始,历代承袭成为习惯。踏青除了欣赏大自然的湖光山色、春光美景之外,还开展各种文娱活动,增添生活情趣。

  清明节流行扫墓,其实扫墓乃清明节前一天寒食节的内容,寒食相传起于晋文公悼念介子推一事。唐玄宗开元二十年诏令天下,“寒食上墓”。因寒食与清明相接,后来就逐渐传成清明扫墓了。明清时期,清明扫墓更为盛行。古时扫墓,孩子们还常要放风筝。有的风筝上安有竹笛,经风一吹能发出响声,犹如筝的声音,据说风筝的名字也就是这么来的。

  清明节还有许多失传的风俗,如古代曾长期流传的戴柳、射柳、打秋千等,据载,辽代风俗最重清明节,上至朝廷下至庶民百姓都以打秋千为乐,仕女云集,踏青之风也极盛。

  据说,插柳的风俗,也是为了纪念“教民稼穑”的农事祖师神农氏的。有的地方,人们把柳枝插在屋檐下,以预报天气,古谚有“柳条青,雨蒙蒙;柳条干,晴了天”的说法。黄巢起义时规定,以“清明为期,戴柳为号”。起义失败后,戴柳的习俗渐被淘汰,只有插柳盛行不衰。杨柳有强大的生命力,俗话说:“有心栽花花不发,无心插柳柳成荫。”柳条插土就活,插到哪里,活到哪里,年年插柳,处处成阴。清明插柳戴柳还有一种说法:原来中国人以清明、七月半和十月朔为三大鬼节,是百鬼出没讨索之时。人们为防止鬼的侵扰迫害,而插柳戴柳。柳在人们的心目中有辟邪的功用。受佛教的影响,人们认为柳可以却鬼,而称之为“鬼怖木”,观世音以柳枝沾水济度众生。北魏贾思勰《齐民要术》里说:“取柳枝著户上,百鬼不入家。”清明既是鬼节,值此柳条发芽时节,人们自然纷纷插柳戴柳以辟邪了。汉人有“折柳赠别”的风俗:灞桥在长安东,跨水作桥,汉人送客至此桥,折柳赠别。李白有词云:“年年柳色,灞陵伤别。”古代长安灞桥两岸,堤长十里,一步一柳,由长安东去的人多到此地惜别,折柳枝赠别亲人,因“柳”与“留”谐音,以表示挽留之意。这种习俗最早起源于《诗经.小雅.采薇》里“昔我往矣,杨柳依依”。用离别赠柳来表示难分难离,不忍相别,恋恋不舍的心意。杨柳是春天的标志,在春天中摇曳的杨柳,总是给人以欣欣向荣之感。“折柳赠别”就蕴含着“ 春常在”的祝愿。古人送行折柳相送,也喻意亲人离别去乡正如离枝的柳条,希望他到新的地方,能很快地生根发芽,好像柳枝之随处可活。它是一种对友人的美好祝愿。古人的诗词中也大量提及折柳赠别之事。唐代权德舆诗:“新知折柳赠”,宋代姜白石诗:“别路恐无青柳枝”,明代郭登诗:“年年长自送行人,折尽边城路旁柳。”清代陈维崧词:“柳条今剩几?待折赠。”人们不但见了杨柳会引起别愁,连听到《折杨柳》曲,也会触动离绪。李白《春夜洛城闻笛》:“此夜曲中闻折柳,何人不起故园情。”其实,柳树可以有多方面的象征意义,古人又赋予柳树种种感情,于是借柳寄情便是情理中之事了。

  寒食究竟在清明的前几日?有几种说法。南朝梁宗懔《荆楚岁时记》的记载,冬至后一百零五天称寒食节,这样正好是清明节的前二天。唐代元稹的诗云:“初过寒食一百六”,认为清明节前一天为寒食节,清明节与冬至本身所处的日期,就有一天的差异。因为寒食和清明的日子相近,而古人在寒食中的活动又往往延续到清明。久而久之,寒食和清明也就没有严格区分了。

  清明前后流传着很多传统的风俗活动。如寒食赐火,清明扫墓,踏青郊游,打马球,放风筝,荡秋千,斗鸡,拔河等。这些活动随着岁月的赓续交替,社会的嬗递变化,有的习俗已被淘汰,有的仍遗留至今并赋予了新的内容。

  [1]

寒食节

  要谈清明节,须从古代一个非常有名的,现在已失传的节日——寒食节说起。

  寒食节,又称熟食节、禁烟节,冷节。它的日期,是距冬至一百零五日,也就是距清明不过一天或两天。这个节日的主要节俗就是禁火,不许生火煮食,只能吃备好的熟食、冷食,故而得名。

  寒食节相传是源于春秋时代的晋国,是为了纪念晋国公子的臣子介子推。晋国公子重耳,流亡外国19年,介子推护驾跟随,立下大功,重耳返国即位,即晋文公。介子推便背着老母,躲入绵山。晋文公前往寻找,却怎么也找不到。于是他放火烧山,想把介子推逼出来。不料介子推却和母亲抱着一株大树,宁愿烧死,也不出山。晋文公伤心地下令把绵山改称介山(即山西介休县境内的介山),又下令把介子推被烧死的那一天定为寒食节,以后年年岁岁,每逢寒食节都要禁止生火,吃冷饭,以示追怀之意。

  其实,寒食节的真正起源,是源于古代的钻木、求新火之制。古人因季节不同,用不同的树木钻火,有改季改火之俗。而每次改火之后,就要换取新火。新火未至,就禁止人们生火。这是当时的一件大事。《周礼· 秋官·司煊氏》:“中春以木铎修火禁于国中。”可见当时是摇着木锋,在街上走,下令禁火。这司煊氏,也就是专管取火的小官。在禁火之时,人们就准备一些冷食,以供食用,这样慢慢就成了固定的风俗了。以后,才与介子推的传说相联系,成了寒食节,日期长达一个月。这毕竟不利于健康,以后便缩短日期,从七天、三天逐渐改为一天,唐之后便融合在清明节中了。

  寒食节习俗,有上坟、效游、斗鸡子、荡秋千、打毯、牵钩(拔河)等。其中上坟之俗,是很古老的。有坟必有墓祭,后来因与三月上已招魂续魄之俗相融合,便逐渐定在寒食上祭了。《唐书》记云:“开元二十年敕,寒食上墓,《礼经》无文。近代相传,浸以成俗,宜许上墓同拜扫礼。”宋庄季裕《鸡肋篇》卷上:“寒食上冢,亦不设香火。纸钱挂于茔树。其去乡里者,皆登山望祭。裂帛于空中,谓之掰钱。而京师四方因缘拜扫,遂设酒撰(zhuan,饭食),携家春游。”

  《荆楚岁时记》:“(寒食)斗鸡,镂鸡子(鸡蛋),斗鸡子。”可见南朝时就有斗鸡与斗鸡蛋之戏了。斗鸡今多见,斗鸡蛋多是乡间小儿互相撞碰鸡蛋作为游戏。在古代,用作碰撞争斗的鸡蛋多是染色、雕镂(lou,雕刻)过的,十分精美。画蛋。镂蛋之俗,源于《管子》中所记的“雕卵”。无疑它是由古代食卵求生育的巫术发展而来,成了寒食的节俗。今天民间亦有清明吃蛋之俗(如前述的“子福”)。 寒食打秋干,据《艺文类聚》中记,北方山戎于寒食日打秋千。但这恐怕只是传说而已。刘向别录》记打秋千是在春时,不一定在寒食。又打毯,王建宫词》:“寒食宫人步打毯。”牵钩与打毯等戏,也不一定在寒食举行。

  由于清明节气在寒食第三日,后世随着时间的迁移,逐渐把寒食的习俗移到清明之中。宋代之后,寒食扫墓之俗移到清明之中。踏青春游、荡秋千等俗也只在清明时举行。清明节便由一个单纯的农业节气上升为重要的大节日了,寒食节的影响也就消失了。但寒食的食俗有若干变形的方式却传承下来了,并保存于清明节中。

【25个民族过清明节】

  中国有25个民族过清明节,虽然各地习俗不尽相同,但扫墓祭祖、踏青郊游是基本主题。受汉族文化的影响,中国的满族、赫哲族、壮族、鄂伦春族、侗族、土家族、苗族、瑶族、黎族、水族、京族、羌族等24个少数民族,也都有过清明节习俗。

  台湾清明节中国幅员辽阔,南北气候不一,所以清明节也因地而异,有二月初二的,也有三月初三的。台湾的清明节是从前一年冬至开始算起的第105天,台湾的漳州籍人清明节则是在农历三月初三。台湾清明节习俗和闽南差不多,台湾客家人祭祖扫墓的时间是从元宵节过后便开始,日期由每家自定,一直到清明为止。台湾民众的扫墓习俗,一般可分为两种:一种是一般祭扫,仪式及祭祀的东西比较简单,大都只供一些米糕、粿类和糕饼;二是修整祖墓,祭礼相当隆重,供祭的祭礼一般包括各种祭礼品十二种蔬菜及粿类、糕饼等。扫墓时一定要在坟墓的四周献置“墓纸”(用五色纸剪成长方形)每张纸压上小石头,还得放一沓在墓碑上。这个仪式俗称“挂纸”,是献给祖先的钱。如果是培墓即修整祖墓,全家人要围在坟墓四周吃红蛋,蛋壳就撒在墓地上,含有新陈代谢、生生不息的吉祥意思。扫墓的同时,也要祭拜长期站在一旁守护墓地及祖先安灵的土地公(有一块小石碑),一方面是慰劳,更有感恩图报的意思。台湾还有一个特殊习俗,如果在这一年内家中有喜事,扫墓时要整修坟墓,还得准备一个小红灯(油灯)点在墓前,回家时再带回家,据说可招来更多的喜气和吉祥。过去的台湾农村,每当扫完墓之后,都会有一群孩子前来讨粿类,来的人愈多,表示这一家族日后将愈发达,主人们也都乐意分送“发粿”或金钱给那些孩子们。后因台湾墓地减少而实行骨灰塔,不少人把骨灰盒放置骨灰塔上,每到清明则到骨灰塔去祭拜,也同样起祭拜祖先的作用。由于人们观念的逐步改变,祭扫祖墓的仪式也省略了许多。 清明节诗句在中国古代,清明节是一个内涵丰富情感的日子,也是文人墨客诗兴大发的日子。在所有二十四节气的吟咏中,清明独占鳌头,数量最多、质量最高。折柳赠别(《唐诗三百首》)查阅《全唐诗》和《全宋词》,内容中有“清明”“寒食”字样的唐诗有335首,宋词更多达520首,而“春分”“芒种”“处暑”等大多数节气诗歌则只有10首8首左右。

【清明节由来】

  中国传统的清明节大约始于周代,已有二千五百多年的历史。它在古代不如前一日的寒食节重要,因为清明及寒食节的日期接近,民间渐渐将两者的习俗融合,到了隋唐年间(581至907年),清明节和寒食节便渐渐融合为同一个节日,成为扫墓祭祖的日子,即今天的清明节。从此,清明节踏青扫墓成为中华民族一种固定的风俗。

  清明节,又称扫坟节、鬼节、冥节,与七月十五中元节及十月初一寒衣节合称三冥节,都与祭祀鬼神有关。

  清明节,又叫踏青节,按阳历来说,它是在每年的4月4日至6日之间,正是春光明媚草木吐绿的时节,也正是人们春游(古代叫踏青)的好时候,所以古人有清明踏青,并开展一系列体育活动的习俗。 清明节古时也叫三月节,已有2000多年历史。

  公历四月五日前后为清明节,是二十四节气之一。在二十四个节气中,既是节气又是节日的只有清明和冬至。它的原意是大自然已经到了转暖的时候,万物开始复苏,可以春耕播种了。中国古代将清明分为三候:“一候桐始华;二候田鼠化为鹌;三候虹始见。”意即在这个时节先是白桐花开放,接着喜阴的田鼠不见了,全回到了地下的洞中,然后是雨后的天空可以见到彩虹了。

  由于二十四节气比较客观地反映了一年四季气温、降雨、物候等方面的变化,所以古代劳动人民用它安排农事活动。《淮南子·天文训》云:“春分后十五日,斗指乙,则清明风至。”按《岁时百问》的说法:“万物生长此时,皆清洁而明净。故谓之清明。”清明一到,气温升高,雨量增多,正是春耕春种的大好时节。故有“清明前后,点瓜种豆”、“植树造林,莫过清明”的农谚。可见这个节气与农业生产有着密切的关系。

  但是,清明作为节日,与纯粹的节气又有所不同。节气是中国物候变化、时令顺序的标志,而节日则包含着一定的风俗活动和某种纪念意义。清明节是中国传统节日,也是最重要的祭祀节日,是祭祖和扫墓的日子。扫墓俗称上坟,祭祀死者的一种活动。汉族和一些少数民族大多都是在清明节扫墓。按照旧的习俗,扫墓时,人们要携带酒食果品、纸钱等物品到墓地,将食物供祭在亲人墓前,再将纸钱焚化,为坟墓培上新土,折几枝嫩绿的新枝插在坟上,然后叩头行礼祭拜,最后吃掉酒食回家。唐代诗人杜牧的诗《清明》:“清明时节雨纷纷,路上行人欲断魂。借问酒家何处有?牧童遥指杏花村。”写出了清明节的特殊气氛。 直到今天,清明节祭拜祖先,悼念已逝的亲人的习俗仍很盛行。

  寒食节—-寒食即禁火,只能吃冷或预先煮好的食物。相传这个习俗起源于春秋时代,当时晋国有人欲害死大公子重耳,忠臣介之推(又名介子推)便护送重耳逃亡,甚至在饥寒交迫之际,割下自己的肉给重耳吃,希望日后他安然回国,当上国君,并勤政爱民。

  十多年后,重耳终于回国当上了国君,即春秋五霸之一的晋文公,并逐一犒赏流亡期间曾协助他的人,却忘了介之推,他经旁人提醒,才赶忙差人请介之推前来领赏。可是,介之推和母亲到深山隐居。晋文公与臣子在山中遍寻不获,有人提议放火烧山,介之推是孝子,一定会救母亲出来。可是,大火烧了三日三夜,仍不见介之推。火熄灭后,人们在一棵柳树下发现介之推背着母亲的尸体。晋文公非常伤心和懊悔,将二人安葬在柳树下。晋文公将放火烧山的一天,定为寒食节,规定人民禁止用火,寒食一天,以纪念介之推的忠诚。

  在春光明媚、桃红柳绿的三四月间,中国传统习俗中最重视的节日就是清明节了。清明节就是现在的民族扫墓节。按主日说,约在四月五日前后,按农历,则是在三月上半月。古人把一年分为二十四节气,以这种岁时历法来播种、收成,清明便是二十四节气之一,时在春分后十五天,按“岁时百问”的说法:“万物生长此时,皆清洁而明净。故谓之清明。”所以,“清明”本为节气名,后来加了寒食禁火及埽墓的习俗才形成清明节的。

【清明节习俗】

  清明节的习俗是丰富有趣的,除了讲究禁火、扫墓,还有踏青、荡秋千蹴鞠打马球插柳等一系列风俗体育活动。相传这是因为清明节要寒食禁火,为了防止寒食冷餐伤身,所以大家来参加一些体育活动,以锻炼身体。因此,这个节日中既有祭扫新坟生别死离的悲酸泪,又有踏青游玩的欢笑声,是一个富有特色的节日。

  荡秋千 这是中国古代清明节习俗。秋千,意即揪着皮绳而迁移。它的历史很古老,最早叫千秋,后为了避忌讳,改为秋千。古时的秋千多用树桠枝为架,再栓上彩带做成。后来逐步发展为用两根绳索加上踏板的秋千。荡秋千不仅可以增进健康,而且可以培养勇敢精神,至今为人们特别是儿童所喜爱。

  蹴鞠 鞠是一种皮球,球皮用皮革做成,球内用毛塞紧。蹴鞠,就是用足去踢球。这是古代清明节时人们喜爱的一种游戏。相传是黄帝发明的,最初目的是用来训练武士。

  踏青 又叫春游。古时叫探春、寻春等。三月清明,春回大地,自然界到处呈现一派生机勃勃的景象,正是郊游的大好时光。中国民间长期保持着清明踏青的习惯。

  植树 清明前后,春阳照临,春雨飞洒,种植树苗成活率高,成长快。因此,自古以来,中国就有清明植树的习惯。有人还把清明节叫作“植树节”。植树风俗一直流传至今。1979年,人大常委会规定,每年三月十二日为中国植树节。这对动员全国各族人民积极开展绿化祖国活动,有着十分重要的意义。

  放风筝 也是清明时节人们所喜爱的活动。每逢清明时节,人们不仅白天放,夜间也放。夜里在风筝下或风稳拉线上挂上一串串彩色的小灯笼,象闪烁的明星,被称为“神灯 ”。过去,有的人把风筝放上蓝天后,便剪断牵线,任凭清风把它们送往天涯海角,据说这样能除病消灾,给自己带来好运。

  扫墓 清明扫墓,谓之对祖先的“思时之敬”。其习俗由来已久。明《帝京景物略》载:“三月清明日,男女扫墓,担提尊榼,轿马后挂楮锭,粲粲然满道也。拜者、酹者、哭者、为墓除草添土者,焚楮锭次,以纸钱置坟头。望中无纸钱,则孤坟矣。哭罢,不归也,趋芳树,择园圃,列坐尽醉。”其实,扫墓在秦以前就有了,但不一定是在清明之际,清明扫墓则是秦以后的事。到唐朝才开始盛行。《清通礼》云:“岁,寒食及霜降节,拜扫圹茔,届期素服诣墓,具酒馔及芟剪草木之器,周胝封树,剪除荆草,故称扫墓。”并相传至今。

  清明祭扫仪式本应亲自到茔地去举行,但由于每家经济条件和其它条件不一样,所以祭扫的方式也就有所区别。“烧包袱”是祭奠祖先的主要形式。所谓“包袱”,亦作“包裹”是指孝属从阳世寄往“阴间”的邮包。过去,南纸店有卖所谓“包袱皮”,即用白纸糊一大口袋。有两种形式:一种是用木刻版,把周围印上梵文音译的《往生咒》,中间印一莲座牌位,用来写上收钱亡人的名讳,如:“已故张府君讳云山老大人”字样,既是邮包又是牌位。另一种是素包袱皮,不印任何图案,中间只贴一蓝签,写上亡人名讳即可。亦做主牌用。关于包袱里的冥钱,种类很多。

  一、大烧纸,九K白纸,砸上四行圆钱,每行五枚;

  二、冥钞,这是人间有了洋钱票之后仿制的,上书“天堂银行”、“冥国银行”、“地府阴曹银行”等字样,并有酆都城的图案,多系巨额票面,背后印有佛教《往生咒》;

  三、假洋钱,用硬纸作心,外包银箔,压上与当时通行的银元一样的图案;

  四、用红色印在黄表纸上的《往生咒》,成一圆钱状,故又叫“往生钱”;

  五、用金银箔叠成的元宝、锞子,有的还要用线穿成串,下边缀一彩纸穗。旧时,不拘贫富均有烧包袱的举动。是日,在祠堂或家宅正屋设供案,将包袱放于正中,前设水饺、糕点、水果等供品,烧香秉烛。全家依尊卑长幼行礼后,即可于门外焚化。焚化时,划一大圈,按坟地方向留一缺口。在圈外烧三五张纸,谓之“打发外祟”。

  有的富户要携家带眷乘车坐轿,亲到坟茔去祭扫。届时要修整坟墓,或象征性地给坟头上添添土,还要在上边压些纸钱,让他人看了,知道此坟尚有后人。祭罢,有的围坐聚餐饮酒;有的则放起风筝,甚至互相比赛,进行娱乐活动。妇女和小孩们还要就近折些杨柳枝,将撤下的蒸食供品用柳条穿起来。有的则把柳条编成箩圈状,戴在头上,谓“清明不戴柳,来生变黄狗”。此即是扫墓又是郊游,兴尽方归。

  六、清明节用花,一般来说,白色的花表示哀悼,选择白百合、马蹄莲等用于扫墓是比较合适的,而白玫瑰、栀子花或素色的花则象征着惋惜和怀念。还有的人偏爱蓬莱松、排草等朴素植物。当然,如今扫墓用花也不再拘泥于此,很多市民会根据过世者的年龄和喜好选择花卉种类,如勿忘我、黄玫瑰、红玫瑰、天堂鸟等。

  插柳 据说,插柳的风俗,也是为了纪念“教民稼穑”的农事祖师神农氏的。有的地方,人们把柳枝插在屋檐下,以预报天气,古谚有“柳条青,雨蒙蒙;柳条干,晴了天 ”的说法。黄巢起义时规定,以“清明为期,戴柳为号”。起义失败后,戴柳的习俗渐被淘汰,只有插柳盛行不衰。杨柳有强大的生命力,俗话说:“有心栽花花不发,无心插柳柳成荫。”柳条插土就活,插到哪里,活到哪里,年年插柳,处处成荫。

  清明节春风明媚,绿树成荫。人们在这一天踏青、扫墓、上坟。人人都要戴柳,家家户户门口插柳枝。这个习俗究竟从何而来呢?关于清明节有个传说和宋代大词人柳永有关。据说柳永生活放荡常往来于花街柳巷之中。当时的歌妓无不爱其才华,并以受柳永青睐为荣。但因为生活不轨,柳永一生为仕途所不容,虽中过进士最后却于襄阳贫困而亡。他的墓葬费用都是仰慕他的歌女集资的。每年清明节,歌女们都到他坟前插柳枝以示纪念,久而久之就成了清明插柳的习俗。其实这个习俗早在唐代就有了。唐人认为三月三在河边祭祀时,头戴柳枝可以摆脱毒虫的伤害。宋元以后,清明节插柳的习俗非常盛行,人们踏青玩游回来,在家门口插柳以避免虫疫。无论是民间传说还是史籍典章的记载,清明节插柳总是与避免疾疫有关。春节气候变暖,各种病菌开始繁殖,人们在医疗条件差的情况下只能寄希望于摇摇柳枝了。

  清明插柳戴柳还有一种说法:原来中国人以清明、七月半和十月朔为三大鬼节,是百鬼出没讨索之时。人们为防止鬼的侵扰迫害,而插柳戴柳。柳在人们的心目中有辟邪的功用。受佛教的影响,人们认为柳可以却鬼,而称之为“鬼怖木”,观世音以柳枝沾水济度众生。北魏贾思勰《齐民要术》里说:“取柳枝著户上,百鬼不入家。”清明既是鬼节,值此柳条发芽时节,人们自然纷纷插柳戴柳以辟邪了。汉人有“折柳赠别”的风俗:灞桥在长安东,跨水作桥,汉人送客至此桥,折柳赠别。李白有词云:“年年柳色,灞陵伤别。”古代长安灞桥两岸,堤长十里,一步一柳,由长安东去的人多到此地惜别,折柳枝赠别亲人,因“柳”与“留”谐音,以表示挽留之意。这种习俗最早起源于《诗经.小雅.采薇》里“昔我往矣,杨柳依依”。用离别赠柳来表示难分难离,不忍相别,恋恋不舍的心意。杨柳是春天的标志,在春天中摇曳的杨柳,总是给人以欣欣向荣之感。“折柳赠别”就蕴含着“ 春常在”的祝愿。古人送行折柳相送,也喻意亲人离别去乡正如离枝的柳条,希望他到新的地方,能很快地生根发芽,好像柳枝之随处可活。它是一种对友人的美好祝愿。古人的诗词中也大量提及折柳赠别之事。唐代权德舆诗:“新知折柳赠”,宋代姜白石诗:“别路恐无青柳枝”,明代郭登诗:“年年长自送行人,折尽边城路旁柳。”清代陈维崧词:“柳条今剩几?待折赠。”人们不但见了杨柳会引起别愁,连听到《折杨柳》曲,也会触动离绪。李白《春夜洛城闻笛》:“此夜曲中闻折柳,何人不起故园情。”其实,柳树可以有多方面的象征意义,古人又赋予柳树种种感情,于是借柳寄情便是情理中之事了。鬼不入家。”清明既是鬼节,值此柳条发芽时节,人们自然纷纷插柳戴柳以辟邪了。汉人有“折柳赠别”的风俗:灞桥在长安东,跨水作桥,汉人送客至此桥,折柳赠别。李白有词云:“年年柳色,灞陵伤别。”古代长安灞桥两岸,堤长十里,一步一柳,由长安东去的人多到此地惜别,折柳枝赠别亲人,因“柳”与“留”谐音,以表示挽留之意。这种习俗最早起源于《诗经.小雅.采薇》里“昔我往矣,杨柳依依”。用离别赠柳来表示难分难离,不忍相别,恋恋不舍的心意。杨柳是春天的标志,在春天中摇曳的杨柳,总是给人以欣欣向荣之感。“折柳赠别”就蕴含着“ 春常在”的祝愿。古人送行折柳相送,也喻意亲人离别去乡正如离枝的柳条,希望他到新的地方,能很快地生根发芽,好像柳枝之随处可活。它是一种对友人的美好祝愿。古人的诗词中也大量提及折柳赠别之事。唐代权德舆诗:“新知折柳赠”,宋代姜白石诗:“别路恐无青柳枝”,明代郭登诗:“年年长自送行人,折尽边城路旁柳。”清代陈维崧词:“柳条今剩几?待折赠。”人们不但见了杨柳会引起别愁,连听到《折杨柳》曲,也会触动离绪。李白《春夜洛城闻笛》:“此夜曲中闻折柳,何人不起故园情。”其实,柳树可以有多方面的象征意义,古人又赋予柳树种种感情,于是借柳寄情便是情理中之事了。

  寒食究竟在清明的前几日?有几种说法。南朝梁宗懔《荆楚岁时记》的记载,冬至后一百零五天称寒食节,这样正好是清明节的前二天。唐代元稹的诗云:“初过寒食一百六”,认为清明节前一天为寒食节,清明节与冬至本身所处的日期,就有一天的差异。因为寒食和清明的日子相近,而古人在寒食中的活动又往往延续到清明。久而久之,寒食和清明也就没有严格区分了。

  清明前后流传着很多传统的风俗活动。如寒食赐火,清明扫墓,踏青郊游,打马球,放风筝,荡秋千,斗鸡,拔河等。这些活动随着岁月的赓续交替,社会的嬗递变化,有的习俗已被淘汰,有的仍遗留至今并赋予了新的内容。

  烤饼 在四川一带都用清明菜和面粉辣椒等混合烤制清明饼,色香味极佳。

  清明菜粑:贵州安顺屯堡一带把一种在清明节时期才会有的一种野生植物—– 清明菜(本地话又称为毛毛花,因其形似一朵花,且杆上面有许多小毛毛)和面粉混合,通过一种独特的手工工艺做成“粑粑状”,再包上陷(一般是本地春菜拌肉、“引子”(苏麻籽)拌红糖,酸辣子炒肉等),通过屯堡一带一种独特的土砂锅在煤火上煎烤而成。清明节屯堡人每家每户都会做,由于清明菜是一种纤维植物,一口咬下去会有“拔丝”的现象,口感极佳。可当零食,也可当主食,可放置时间极长,据说是在明朝朱元璋时期百姓为行军打仗之时士兵随带方便而做。

apache日志分析命令

日志格式:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\""

实时查看:
tail -f access_log | awk -F"[" ‘{print $2}’ | awk -F"]" ‘{print $1}’ | uniq -c
结果显示每秒的访问量,如果只关心某个接口,添加grep就行了

按天统计:
cat access_log.20090401 | php -R ‘preg_match("/(GET|POST){1} (\/[^? ]+)/",$argn, $matches);$arr[$matches[2]]++; $sum++;’ -E ‘foreach($arr as $key=>$val) echo $val . "\t" . $val/$sum*100 ."%\t". $key ."\n"; echo "total\t$sum";’ |sort -nr

统计查询字符串里面的某个参数:

cat access_log.20090401 | php -R ‘preg_match("/(GET|POST) [^\"]*entry=([^& ]*)[&
]?/",$argn,$matches);echo $matches[2]."\n";’ | sort -n | uniq -c | sort -rn


匹配2009-08-27~29 三天的日志,用户名以 _[0-9a-z]{5} 结尾:

grep  space /data2/ssologs/login/200908/*2[7-9] | grep "| LoginFlow |" | grep "| 2 |" | grep credentail |  awk -F "|"  –posix ‘$6 ~ / [^_]+_[0-9a-z]{5} $/’

注意: 这里的 {} 属于posix的正则,需要选项 –posix

 

关于js的加载顺序

写JavaScript时,加载顺序是非常关心的,下面的一个脚本演示了加载的顺序:

演示地址:
http://phpor.net/projects/js/test_async.js.php?m=a
http://phpor.net/projects/js/test_async.js.php?m=b
http://phpor.net/projects/js/test_async.js.php?m=c
http://phpor.net/projects/js/test_async.js.php?m=d
http://phpor.net/projects/js/test_async.js.php?m=e

—————————test_async.js.php

<?php

if(isset($_GET[‘js2’])){
        
sleep(1);
        echo 
"alert(‘outer2 js’);";
        exit();
}

if(isset($_GET[‘js’])){
        
//sleep(1);
        
echo ‘document.write(\'<script src="?js2"></script>\’);’;
        echo 
"alert(‘outer js’);";
        exit();
}
if(
$_GET[‘m’] == ‘a’){
        echo 
‘<script src="?js"></script>’;
        echo 
‘<script> alert("inner js"); </script>’;
} else if(
$_GET[‘m’] == ‘b’){
        echo 
‘<script>document.write(\'<script src="?js"><\/script>\’);alert("inner js");</script>’;
} else if(
$_GET[‘m’] == ‘c’){
        echo 
‘<script>document.write(\'<script src="?js"><\/script>\’);</script><script>alert("inner js");</script>’;
} else {
?>
<script>
var loadScript = function (id, scriptSource, charset) {
        var head = document.getElementsByTagName(‘head’)[0];
        var oldScript = document.getElementById(id);
        if (oldScript) {
                head.removeChild(oldScript);
        }
        var newScript = document.createElement(‘script’);
        if (charset) {
                newScript.charset = charset;
        } else { 
                newScript.charset = ‘gb2312’;
        }
        newScript.id = id;
        newScript.type = ‘text/javascript’;
        newScript.src = scriptSource;
        head.appendChild(newScript);
};
</script>
<?php
        
if($_GET[‘m’] == ‘d’) {
                echo 
‘<script >loadScript("scriptid","?js");</script>’;
                echo 
‘<script> alert("inner js"); </script>’;
        } else if(
$_GET[‘m’] == ‘e’){
                echo 
‘<script >loadScript("scriptid","?js");alert("inner js");</script>’;
        }
}

?>

——————————————————

mysql 大小写敏感比较 binary

mysql 的条件语句中默认是大小写不敏感的,就是说 ‘a’=’A’  结果为true;如果才能让 a !=A呢? 使用binary关键字,但是还要注意一下问题:

表结构:

mysql> desc innodb;

+———+————–+——+—–+———+——-+

| Field   | Type         | Null | Key | Default | Extra |

+———+————–+——+—–+———+——-+

| name    | varchar(100) | NO   | PRI |         |       |

| content | mediumtext   | YES  |     | NULL    |       |

+———+————–+——+—–+———+——-+

2 rows in set (0.09 sec)

 

表内容:

mysql> select * from innodb;

+——+———+

| name | content |

+——+———+

| c    | d       |

| d    | d       |

| e    | d       |

| kkk  | ttttt   |

+——+———+

4 rows in set (0.01 sec)

 

查询使用了主键索引:

mysql> desc select * from innodb where  name= "C";
+—-+————-+——–+——+—————+———+———+——-+——+————-+
| id | select_type | table  | type | possible_keys | key     | key_len | ref   | rows | Extra       |
+—-+————-+——–+——+—————+———+———+——-+——+————-+
|  1 | SIMPLE      | innodb | ref  | PRIMARY       | PRIMARY | 202     | const |    1 | Using where |
+—-+————-+——–+——+—————+———+———+——-+——+————-+
1 row in set (0.00 sec)

 

使用binary时,主键索引用不上了:

mysql> desc select * from innodb where binary name= "C";
+—-+————-+——–+——+—————+——+———+——+——+————-+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+—-+————-+——–+——+—————+——+———+——+——+————-+
|  1 | SIMPLE      | innodb | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
+—-+————-+——–+——+—————+——+———+——+——+————-+
1 row in set (0.01 sec)

 

修改表结构,直接将列设置为

mysql> alter table innodb modify name  varchar(100) BINARY NOT NULL default ” ;
Query OK, 4 rows affected (0.40 sec)
Records: 4  Duplicates: 0  Warnings: 0

 

显示name列是binary的了,查看一下:

mysql> show create table innodb;
+——–+———————————————————————————
| Table  | Create Table
+——–+———————————————————————————
| innodb | CREATE TABLE innodb (
  name varchar(100) character set gbk collate gbk_bin NOT NULL default ”,
  content mediumtext,
  PRIMARY KEY  (name)
) ENGINE=InnoDB DEFAULT CHARSET=gbk |
+——–+———————————————————————————
1 row in set (0.01 sec)

 

再测试select看看是否能用上索引:

 

mysql> desc select * from innodb where name= "C";
+—-+————-+——-+——+—————+——+———+——+——+—————————————————–+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+—-+————-+——-+——+—————+——+———+——+——+—————————————————–+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
+—-+————-+——-+——+—————+——+———+——+——+—————————————————–+
1 row in set (0.00 sec)

 

很遗憾,索引还是没有用上

 

结论: 主键不要设置为binary的,否则索引无效,如果真的希望主键是大小写敏感的,可能有别的办法,继续探索。。。

 

binary的试试:

IE8新感受

听说IE8 出来了,就试个新儿,装了IE8一周了,逐渐发现了一些和原来不一样的东西。

1.  添加了开发人员工具
     使用这个工具就可以调试js了,而且可以单步调试,这对IE来说,确实是一个革新,以前遇到js的问题,就打开firfox,现在不同了,IE单步调试js,一个字“爽”

2. 新标签页打开
     IE7添加了标签页,但是总是要按住一个功能键才能从新的标签页打开,否则就打开新窗口;现在IE8可以直接新的标签页里打开了

3. 多进程之间的通信
     IE7里面,一个窗口登录后,在新打开一个IE窗口,状态是未登录的;就是说没有进程间的通信,无意间发现IE8虽然多个窗口也是多个进程,但是一个窗口登录了,另一个窗口立马就知道了

 

苹果apple iphone蓝牙破解软件iBluetooth被破解

      在经过数月的等待过后,来自Medevil的蓝牙破解程序iBluetooth终于可以通过Cydia上iSpazio的源进行下载。

      软件目前可以进行蓝牙文件的传输,据称已经在很多平台上进行了测试,平均传输速率为70kb/s.

      软件需要到Medevil.net进行注册,免费使用期7天,完全版售价为3.99欧元。
由于目前Medevil的网站由于流量过大暂时瘫痪,暂时没有办法取得软件注册,网上只有一些零星的试用报告,更大范围的使用结果还不得而知。

      另外iSpazio还表示目前软件还是存在一些bug,可能会需要经常性的respring或是重启。所以大家可以稍微观望一下或是谨慎使用。