I/O 多路选择示例 (select)

书中自有言如玉呀,select函数的使用方法,我在中间加入了一些printf语言,更方便理解程序的流程
客户端用之前的TCP例子就行了,见http://www.kumouse.com/article.asp?id=141

[ssj@main test]$ cat selectserver.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>

#define MAX 80

int port=65533;

void my_turn(char *p)
{sleep(5);
if (p == NULL)return;
while( *p != '')
{
if( *p >= (char)0x61 && *p <= (char)0x7a)
*p=(char)((int)*p-(int)0x20);
p++;
}
}

int main(void)
{
struct sockaddr_in sin,cin;
int lfd,cfd,sfd,rdy,client[FD_SETSIZE],maxi,maxfd;
fd_set rset,allset;
socklen_t addr_len;
char buf[MAX],str[INET_ADDRSTRLEN];
int i,n,len,opt=1;

bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=INADDR_ANY;
sin.sin_port=htons(port);

lfd=socket(AF_INET,SOCK_STREAM,0);
if(lfd==-1)
{perror("Fail to socket");exit(1); }

setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

if((n=bind(lfd,(struct sockaddr *)&sin,sizeof(sin)))==-1)
{perror("Fail to bind");exit(1);}

if((n=listen(lfd,20))==-1)
{perror("Fail to listen");exit(1);}

printf("running….n");

maxfd=lfd;
maxi=-1;

for(i=0;i<FD_SETSIZE;i++)
{client[i]=-1;}

FD_ZERO(&allset);
FD_SET(lfd,&allset);

while(1){
rset=allset;
rdy=select(maxfd+1,&rset,NULL,NULL,NULL);
printf("%dn",rdy);
if(FD_ISSET(lfd,&rset)){
printf("p1n");
addr_len=sizeof(sin);
if((cfd=accept(lfd,(struct sockaddr *)&cin,&addr_len))==-1)
{perror("Fail to accept");exit(1);}

for(i=0;i<FD_SETSIZE;i++)
if(client[i]<0){client[i]=cfd;break;}

if(i==FD_SETSIZE){printf("too many clientsn");exit(1);}

FD_SET(cfd,&allset);

if(cfd>maxfd)
maxfd=cfd;
if(i>maxi)
maxi=i;
if(–rdy<=0)
continue;
}

for(i=0;i<=maxi;i++){
if((sfd=client[i])<0)continue;

if(FD_ISSET(sfd,&rset)){
if((n=read(sfd,buf,MAX))==0){
printf("the other side has been close.n");
fflush(stdout);
close(sfd);
FD_CLR(sfd,&allset);
client[i]=-1;
}
else{
inet_ntop(AF_INET,&cin.sin_addr,str,sizeof(str));
printf("client IP:%s:%dn",str,ntohs(cin.sin_port));
my_turn(buf);
if((n=write(sfd,buf,n))==-1)exit(1);
}
if(–rdy<=0)break;
}
}
}
close(lfd);
return 0;
}

一个非阻塞方式的网络程序模型(UDP)

服务器端:

[ssj@main test]$ cat noneasyserver.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#define MAX 80

void my_turn(char *p)
{
if (p == NULL)return;
while( *p != '')
{
if( *p >= (char)0x61 && *p <= (char)0x7a)
*p=(char)((int)*p-(int)0x20);
p++;
}
}

int main(void)
{
struct sockaddr_in sin,cin;
int sfd;
int port=65533;
socklen_t addr_len;
char buf[MAX];
char addr_p[INET_ADDRSTRLEN];
int n,n1,flags;

bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=INADDR_ANY;
sin.sin_port=htons(port);

sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd==-1)
{
perror("Fail to socket");
exit(1);
}

if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))==-1)
{
perror("Fail to bind");
exit(1);
}

flags=fcntl(sfd,F_GETFL);
flags |= O_NONBLOCK;

if(fcntl(sfd,F_SETFL,flags)==-1)
{
perror("Fail to fcntl");
exit(1);
}

while(1)
{
sleep(5);
bzero(buf,sizeof(buf));
addr_len=sizeof(sin);

n=recvfrom(sfd,buf,MAX,0,(struct sockaddr *)&cin,&addr_len);
if(n==-1&&errno!=EAGAIN)
{
perror("Fail to receiven");
exit(1);
}else if(errno==EAGAIN)
printf("socket are not ready nown");

if(n>=0)
{
inet_ntop(AF_INET,&cin.sin_addr,addr_p,sizeof(addr_p));
printf("Client IP is %s:%dn",addr_p,ntohs(cin.sin_port));
printf("type:%sn",buf);
my_turn(buf);

n1=sendto(sfd,buf,n,0,(struct sockaddr *)&cin,addr_len);
if(n1==-1&&errno!=EAGAIN)
{
perror("Fail to sendto");exit(1);
}else if(errno==EAGAIN)
{
printf("socket ate not ready nown");
}
}

}
if(close(sfd)==-1)
{
perror("Fail to close");exit(1);
}
return 0;
}

客户端:

[ssj@main test]$ cat noneasyclient.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#define MAX 80

int main(void)
{
struct sockaddr_in sin,cin;
int port=65533;
socklen_t addr_len;
int sfd;
char buf[MAX];
char add_p[INET_ADDRSTRLEN];
int n;

bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
inet_pton(AF_INET,"127.0.0.1",&sin.sin_addr);
sin.sin_port=htons(port);

sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd==-1){perror("Fail to socket");exit(1);}

if(fgets(buf,MAX,stdin)==NULL){perror("Fail to fget");exit(1);}

n=sendto(sfd,buf,strlen(buf)+1,0,(struct sockaddr *)&sin,sizeof(sin));
if(n==-1){perror("Fail to send");exit(1);}

addr_len=sizeof(sin);

n=recvfrom(sfd,buf,MAX,0,(struct sockaddr *)&cin,&addr_len);
if(n==-1)
{
perror("Fail to receiven");
exit(1);
}else
printf("from server:%sn",buf);

if(close(sfd)==-1)
{
perror("Fail to close");exit(1);
}
return 0;

}

一个不完善的多线程服务器模型

根据:http://www.kumouse.com/article.asp?id=141
中的服务端改写而成,刚学不久,只是练练手的。有高人路过,还请指点
字符串长度n没有当参数传递,所以会是0,退出要第二次发数据才行,其实用消息处理函数,CTRL+C就可能搞定了
[ssj@main test]$ cat rs_easyserver.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#define MAX 200
#define BB 16
int k=0;
void my_turn(char *p)
{sleep(10);
if (p == NULL)return;
while( *p != '')
{
if( *p >= (char)0x61 && *p <= (char)0x7a)
*p=(char)((int)*p-(int)0x20);
p++;
}
}

typedef struct arg_struct ARG;
struct arg_struct{
int cfd;
};
void *f1(void *arg)
{
char buf[MAX];
char addr_p[BB];
int n,cfd;
ARG *p=(ARG *)arg;
cfd=p->cfd;
n=recv(cfd,buf,MAX,0);
if (n==-1)
{
perror("Fail to recv");
exit(1);
}
else if(n==0)
{
printf("the connect closedn");
close(cfd);
exit(1);
}
if (strcmp(buf,"close")==0){k=1;}
printf("type:%sn",buf);
my_turn(buf);
printf("turn type:%sn=================================n",buf);
n=send(cfd,buf,n,0);
if(n==-1){
perror("Fail to send");
exit(1);
}
if(close(cfd)==-1)
{
perror("Fail to close");
exit(1);
}

}

int main(void)
{
struct sockaddr_in sin,cin;
struct sockaddr *tmp;
int lfd,cfd;
socklen_t len;
char buf[MAX];
char addr_p[BB];
int n,err,port = 65533;
pthread_t tid;
ARG arg;
bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=INADDR_ANY;
sin.sin_port=htons(port);

if((lfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("Fail to create socket");
exit(1);
}

if(bind(lfd,(struct sockaddr *)&sin,sizeof(sin))==-1)
{
perror("Fail to bind");
exit(1);
}
if(listen(lfd,10)==-1)
{
perror("Fail to listen");
exit(1);
}
printf("running……….n");

while(1)
{
if((cfd=accept(lfd,(struct sockaddr *)&cin,&len))==-1)
{
perror("Fail to accept");
exit(1);
}else{
inet_ntop(AF_INET,&cin.sin_addr,addr_p,sizeof(addr_p));
// printf("client IP is:%s:%d size:%dn",addr_p,ntohs(cin.sin_port),n);
arg.cfd=cfd;
err=pthread_create(&tid,NULL,f1,(void *)&arg);
if (err!=0){printf("%sn",strerror(err));exit(1);}
}
printf("client IP is:%s:%d Pthread:%d size:%dn",addr_p,ntohs(cin.sin_port),tid,n);
if (k==1)
{close(cfd);close(lfd);exit(0);}
}

if(close(cfd)==-1)
{
perror("Fail to close");
exit(1);
}

if(close(lfd)==-1)
{
perror("fail close");
exit(1);
}
return 0;
}

注:编译时加-lpthread参数,pthread_create不在默认库里

一个服务器模型的测试(例子)

服务器端:
[ssj@main test]$ cat easyserver.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#define MAX 200 /*缓冲区大小*/
#define BB 16 /*IP地址长度 IPV4是16,IPV6是28*/
void my_turn(char *p) /*字符处理函数,小写变大写,linux下没有strupr了???*/
{
if (p == NULL)return;
while( *p != '')
{
if( *p >= (char)0x61 && *p <= (char)0x7a)
*p=(char)((int)*p-(int)0x20);
p++;
}
}

int main(void)
{
struct sockaddr_in sin,cin; /*sin本地IP地址结构,cin客户端IP地址结构*/
int lfd,cfd; /*lfd本地socket套接字描述符,cfd,由accept建立的*/
socklen_t len; /*客户端IP长度*/
char buf[MAX]; /*缓冲区*/
char addr_p[BB]; /*IP地址十进制字符串*/
int port = 65533; /*绑定的端口*/
int n; /*收到的数据长度*/
bzero(&sin,sizeof(sin)); /*初始化sin*/
sin.sin_family=AF_INET; /*定义为IPV4*/
sin.sin_addr.s_addr=INADDR_ANY; /*服务器可以接受任意地址*/
sin.sin_port=htons(port); /*把IP地址转有16位字节序,并赋值*/

lfd=socket(AF_INET,SOCK_STREAM,0); /*建立套接字*/
bind(lfd,(struct sockaddr *)&sin,sizeof(sin)); /*绑定端口与套接字*/
listen(lfd,10); /*监听,并设置最大队列为10*/
printf("running……….n");

while(1) /*循环处理客户的连接请求*/
{
cfd=accept(lfd,(struct sockaddr *)&cin,&len);
n=read(cfd,buf,MAX);
inet_ntop(AF_INET,&cin.sin_addr,addr_p,sizeof(addr_p));
printf("client IP is:%s:%d size:%dn",addr_p,ntohs(cin.sin_port),n);
if (strcmp(buf,"close")==0) /*是否退出*/
{
write(cfd,"server done",12);
close(cfd);
close(lfd);
printf("server done.n");
exit(0);
}
printf("type:%sn",buf);
my_turn(buf);
printf("turn type:%sn=================================n",buf);
write(cfd,buf,n);
close(cfd);
}
if(close(lfd)==-1) /*收尾,实际上,上边的while是个死循环,用ctrl+c退出,或用close退出,都执行不到这里*/
{
perror("fail close");
exit(1);
}
return 0;
}

客户端:
[ssj@main test]$ cat easyclient.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#define MAX 200

int main(int argc,char * argv[])
{
struct sockaddr_in pin;
struct sockaddr_in *apin=&pin;
char buf[MAX];
int sfd,port=65533;
char *str="ssj test";

if (argc>1)
{
str=argv[1];
}
bzero(&pin,sizeof(pin));
pin.sin_family=AF_INET;
inet_pton(AF_INET,"127.0.0.1",&pin.sin_addr);
pin.sin_port=htons(port);

sfd=socket(AF_INET,SOCK_STREAM,0);
connect(sfd,(struct sockaddr *)&pin,sizeof(pin));
write(sfd,str,strlen(str)+1);
read(sfd,buf,MAX);
printf("recive:%sn",buf);
close(sfd);
return 0;
}

======================================
更完善的一个版本(服务器)
[ssj@main test]$ cat easyserver.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include "ssjio.c"
#define MAX 200
#define BB 16
void my_turn(char *p)
{
if (p == NULL)return;
while( *p != '')
{
if( *p >= (char)0x61 && *p <= (char)0x7a)
*p=(char)((int)*p-(int)0x20);
p++;
}
}

int main(void)
{
struct sockaddr_in sin,cin;
int lfd,cfd;
socklen_t len;
char buf[MAX];
char addr_p[BB];
int port = 65533;
int n;
bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=INADDR_ANY;
sin.sin_port=htons(port);

if((lfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("Fail to create socket");
exit(1);
}

if(bind(lfd,(struct sockaddr *)&sin,sizeof(sin))==-1)
{
perror("Fail to bind");
exit(1);
}
if(listen(lfd,10)==-1)
{
perror("Fail to listen");
exit(1);
}
printf("running……….n");

while(1)
{
if((cfd=accept(lfd,(struct sockaddr *)&cin,&len))==-1)
{
perror("Fail to accept");
exit(1);
}

n=ssj_read(cfd,buf,MAX);
if (n==-1)
exit(1);
else if(n==0)
{
printf("the connect closedn");
close(cfd);
continue;
}

inet_ntop(AF_INET,&cin.sin_addr,addr_p,sizeof(addr_p));
printf("client IP is:%s:%d size:%dn",addr_p,ntohs(cin.sin_port),n);
if (strcmp(buf,"close")==0)
{
n=ssj_write(cfd,"server done",12);
if(n==-1)
exit(1);
close(cfd);
close(lfd);
printf("server done.n");
exit(0);
}
printf("type:%sn",buf);
my_turn(buf);
printf("turn type:%sn=================================n",buf);
n=ssj_write(cfd,buf,n);
if(n==-1)
exit(1);

if(close(cfd)==-1)
{
perror("Fail to close");
exit(1);
}
}
if(close(lfd)==-1)
{
perror("fail close");
exit(1);
}
return 0;
}

=========================
[ssj@main test]$ cat ssjio.c
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

ssize_t ssj_read(int fd,void *buf,size_t length)
{
ssize_t done=length;
done=read(fd,buf,length);
return done;
}

ssize_t ssj_write(int fd,void *buf,size_t length)
{
ssize_t done=length;
while(done>0)
{
done=write(fd,buf,length);
if(done!=length)
if (errno==EINTR)
done=length;
else{
perror("Fail to write");
return -1;
}
else
break;
}
return done;
}

客户端同理

关于 linux 中 进程与线程 新的理解

进程 比如用fork函数数建立的子进程,一个是重量级进程,他有自己独立的.data 与.bss 堆 和 栈,只是共享了父进程的代码段而以。
vfork共享了父进程的一切。
而说到线程,LINUX的线程的概念,我个人理解,它本来主是个轻量级的进程,线程共享父线程绝大部分资源,只有独立的栈。

这么说来,进程和线程从实质上讲没有多大区别。在linux中线程只是一个轻量级的进程而以。

快速排序 - 分治策略

看了书之后,自己写了一遍,留个印记
[ssj@main ~]$ cat my.c
#include <stdio.h>
int data[]={2,4,3,34,32,4,23,4,234,234,2,532,34,1,31,5,21,312,3,1523,12,3};
quick_sort(int data[],int low,int high)
{
int i,j,pivot;
if (low<high)
{
i=low;
j=high;
pivot=data[low];

while(i<j){
while(i<j&&data[j]>=pivot)j–;
if(i<j)data[i++]=data[j];
while(i<j&&data[i]<=pivot)i++;
if(i<j)data[j–]=data[i];
}
data[i]=pivot;
quick_sort(data,low,i-1);
quick_sort(data,i+1,high);

}

}
main()
{
int i;
for(i=0;i<=22;i++)
{printf("%d ",data[i]);}
printf("n");
quick_sort(data,0,22);
for(i=0;i<=22;i++){printf("%d ",data[i]);}
printf("n");

}

进程与线程的关系

进程的两个特点:
资源所有权:进程是一个可拥有资源的独立单位;
调度/执行:进程同时又是一个可以独立调度和分派的基本单位;

引入线程的目的:
因为进程是一个资源拥有者,因而在进程的创建、撤消和切换中,系统必须为之付出较大的时空
开销。也因此,在系统中所设置的进程数目不宜过多,进程切换的频率也不宜过高,同时也限制了并
发程序的进一步提高。在操作系统中引入线程,是为了减少程序并发执行时所付出的时空开销,使操
作系统具有更好的并发性。

线程的实质:
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,一个进程可有多个线程;
线程除运行必需的资源外,不拥有系统资源,但它可与同属一进程的其它线程共享进程所拥有的全部资源;
一个线程可创建和撤消另一线程;同一进程中的线程间可并发执行;
线程间相互制约;线程在运行中呈现间断性;
线程有就绪、阻塞、执行三种基本状态;

线程与进程的比较
引入线程的OS
调度:线程为调度和分派的基本单位。进程为拥有资源的基本单位。
并发性:进程间可并发执行,一个进程中的多个线程间也可并发执行。
拥有资源:进程是拥有资源的一个独立单位线程不拥有系统资源。
系统开销:线程切换的开销远小于进程切换的开销;有的系统线程切换、同步和通信都无须OS内核的干预

传统的OS
调度:拥有资源和独立调度、分派的基本单位都是进程。
并发性:进程间可并发执行。
拥有资源:进程是拥有资源的一个独立单位。
系统开销:进程切换的开销远大于线程切换的开销;进程切换涉及OS内核。

线程的功能特征
和进程一样,线程具有执行状态,且可以与另一个线程同步。
线程状态—-和进程一样,线程的主要状态有运行、就绪和阻塞。一般来说,挂起状态对线程
没有什么意义。与线程状态变化相关的有四种基本操作:
  产生(Spawn): 当产生一个新进程时,同时也为该进程产生一个线程,随后,进程中的线程可以
  在同一个进程中产生另一个线程,并为新线程提供指令指针和参数。
  阻塞(Block): 当线程需要等待一个事件时,它将自己阻塞,此时处理器转而执行另一个就绪线程。
  解除阻塞(Unlock): 当阻塞一个线程的事件发生时,该线程被转移到就绪队列中。
  结束(Finish): 当一个线程完成时,其寄存器上下文和栈都被释放。
  线程同步—-一个线程对资源任何的修改都会影响同一个进程中其他线程的环境。因此,需要对各种
  线程的活动进行同步。

线程的分类
线程可分以下两类:
内核支持线程—-线程的创建、撤消和切换都由内核实现。
用户级线程——线程的创建、撤消和切换都不利用系统调用来实现,与内核无关。

两类线程的比较:
内核支持线程
线程的调度与切换速度:与进程的调度与切换十分相似。
系统调用:调度以线程为单位。
线程执行时间:线程多的进程获得CPU时

用户级线程
线程的调度与切换速度:发生在一个应用进程的各线程间,无须OS内核的干预,规则远比进程调度和切换的规则简单。切换速度特别快。
系统调用:一个线程调度看作整个进程的行为。
线程执行时间:进程运行速度与其拥有线程的数量成反比。

C 优先级与结合性

优先级:决定哪部分表达式先计算。
结合性:计算时是从左向右顺序,还是从右向左的顺序。

例1:
b=++a;

先看优先级:++ 优先级比 = 要高,先算++。
再看结合性:++ 的结合性是从右到左,这里就是它,直接算。
现在就剩下 = 号了,优先级就它一个了,但结合性还是 从右到左,那么现在把a 的值取出来赋值给 b 。
所以: 整个结果相当于
a = a + 1; b=a;

例2:
b=a++;

先看优先级,++ 虽然高,但是后置的(它的结合性是从左到右),这就意味着它返回左值。而返回值后就必须进行下面的计算
这里是 = ,运算全部完成后才能进行自身++运算,所以它最后算。我们这里先看 = ,再看结合性: 从右到左。故取 a 的值
赋值给 b ; 最后 a 的值加1 。
相当于: b=a; a = a + 1;

例3:
a+=b-=++c+4+e++;

这个够复杂吧,谁先? 单目运算符前缀 ++ 先算,然后是 + ,赋值运算最后。
然后看结合性。 -= += 都是从右到左,右边先算。故:
上例分解为:++c;b= b- e+c+4;a=a+b;e++

赋值运算符:结合性从右到左
先确定优先级,然后确定结合性。相同优先级的前提下,就要看结合性
结合性表示的是同级优先级,即同级运算符中的优先级。
优先级表示的是全局优先级,即不同运算符中的优先级。

对于自增自减表达式
前缀:先于表达式中其它部分的运算进行计算;
后缀:后于表达式中其它部分的运算进行计算。

++A ; 结合性,从右到左。 变量在右,返回右值。
//先看到 ++ 再看到 A ,返回 A 时 A 已经自增。

A++ ; 结合性,从左到右。 变量在左,返回左值。
//先看到 A,可以返回值,直接返回。A 本身再自增。

再来看看 B=A++; B=++A; 很容易就知道运算关系是怎么样的了,下面进行说明:

A++,执行后置运算,后计算A自增。先返回变量A的值参与表达式中其它部分的运算,整个表达式计算完成后,A才自增。
因其间返回的临时值参是一个常量,故该表达式不能写成:
A++ = 100;// 常量不能赋值

++A,执行前置运算,先计算A自增,然后返回A自增后的值。因为A自增操作已经完成,不必返回临时常量,直接返回A本身即可。
所以该表达式最终返回值是一个变量,故可以写成:
++A = 200; // 变量可以赋值

注意,理解它们, ++A, A++ ,要把它们当一个整体来看,即最小单位。在这里是没什么左右的,不要再分解它们。

自己总结的优先级
1. 括号操作符与关联和后置的自加自减(同级从左到右结合)
() isdigit('1')
[] array[4]
-> prt->age=34;
. *obj.age=34;
++ i++
— i–

2. 单字元的前置运算符(从右到左)
! if(!done)
~ flages=~flages;
++ ++i
— –i
+ int i=+1;
– int i=-1;
* int *p;
& p=&a;
sizeof sizeof(int);

3.数字运算符(乘除取模,高于加减 从左到右)

* i=2*4;
/ i=4/2;
% i=4%3;

+ i=2+4;
– i=4-2;

4.位移运算(从左到右)
>> int flages=flages<<2;
<<

5.比较大小(<,>高于==,!= 从左到右)
< if (i<2)
<=
>
>=

== if (i==2)
!=

6.位运算(&,^,|优先级从高到低,从左向右)
& flages=flages&42;
^
|

7.逻辑运算(从左到右)
&&
||

8.(右向左)
? : int i=(a>b)?a:b

9.赋值(从右向左)
=,+=,-=,*=,/=,%=,&=,^=,|=,<<=,>>=

10.
throw throw eclass("message");

11.逗号
, for (i=0,j=0;i<10;i++,j++)

ssh 配置 ssh_config sshd_config

ssh_config

# Host *  (只对能够匹配后面字串的计算机有效。“*”表示所有的计算机)
# ForwardAgent no  (设置连接是否经过验证代理(如果存在)转发给远程计算机)
# ForwardX11 no  (设置X11连接是否被自动重定向到安全的通道和显示集)
# RhostsRSAAuthentication no  (设置是否使用用RSA算法的基于rhosts的安全验证)
# RSAAuthentication yes  (设置是否使用RSA算法进行安全验证)
# PasswordAuthentication yes  (设置是否使用口令验证)
# HostbasedAuthentication no  (若设置为yes,则尝试着进行rhosts身份验证。对于安全要求更高的系统,请将其设置为no(默认值))
# GSSAPIAuthentication no  (ssh的会话直到DNS请求超时才会继续下去,建意no)
# GSSAPIDelegateCredentials no  (ssh的会话直到DNS请求超时才会继续下去,建意no)
# BatchMode no  (如果设为“yes”,passphrase/password(交互式输入口令)的提示将被禁止。
当不能交互式输入口令的时候,这个选项对脚本文件和批处理任务十分有用)
# CheckHostIP yes  (设置ssh是否查看连接到服务器的主机的IP地址以防止DNS欺骗。建议设置为“yes”)
# AddressFamily any  (设置允许的地址)
# ConnectTimeout 0  (连接超时)
# StrictHostKeyChecking ask  (如果设置成“yes”,ssh就不会自动把计算机的密匙加入“$HOME/.ssh)
# IdentityFile ~/.ssh/identity  (设置从哪个文件读取用户的RSA安全验证标识)
# IdentityFile ~/.ssh/id_rsa
# IdentityFile ~/.ssh/id_dsa
# Port 22  (设置连接到远程主机的端口)
# Protocol 2,1  (设置协议版本,建意用2)
# Cipher 3des  (设置加密用的密码)
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
# EscapeChar ~  (设置escape字符)
# Tunnel no  (隧道模式)
# TunnelDevice any:any
# PermitLocalCommand no
# VisualHostKey no

=======================================================

sshd_config

#Port 22  (设置sshd监听的端口号)
#AddressFamily any
#ListenAddress 0.0.0.0  (设置sshd服务器绑定的IP地址)
#ListenAddress ::

Protocol 2  (设置协议版本)

# HostKey for protocol version 1
#HostKey /etc/ssh/ssh_host_key  (设置包含计算机私人密匙的文件)
# HostKeys for protocol version 2
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key

# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h  (KeyRegenerationInterval 3600)
#ServerKeyBits 1024  (定义服务器密匙的位数)

# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH  (设置在记录来自sshd的消息的时候,是否给出“facility code”)
SyslogFacility AUTHPRIV
#LogLevel INFO  (设置记录sshd日志消息的层次。INFO是一个好的选择。查看sshd的man帮
助页,已获取更多的信息)

# Authentication:

#LoginGraceTime 2m  (设置如果用户不能成功登录,在切断连接之前服务器需要等待的时间)
#PermitRootLogin yes  (设置root能不能用ssh登录。这个选项一定不要设成“yes”)
#StrictModes yes (设置ssh在接收登录请求之前是否检查用户家目录和rhosts文件的权限和所
有权。这通常是必要的,因为新手经常会把自己的目录和文件设成任何人都有写权限)
#MaxAuthTries 6 (限制登陆密码输错次数)
#MaxSessions 10

#RSAAuthentication yes  (设置是否允许用rhosts或“/etc/hosts.equiv”加上RSA进行安全验证)
#PubkeyAuthentication yes
#AuthorizedKeysFile  .ssh/authorized_keys

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no  (设置是否允许用rhosts或“/etc/hosts.equiv”加上RSA进行安全验证)
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no (设置ssh daemon是否在进行RhostsRSAAuthentication安全验证
的时候忽略用户的“$HOME/.ssh/known_hosts)
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes (设置验证的时候是否使用“rhosts”和“shosts”文件)

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes  (设置是否允许口令验证)
#PermitEmptyPasswords no  (设置是否允许用口令为空的帐号登录)
PasswordAuthentication yes

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no

# GSSAPI options
#GSSAPIAuthentication no
GSSAPIAuthentication yes
#GSSAPICleanupCredentials yes
GSSAPICleanupCredentials yes

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
#UsePAM no
UsePAM yes

# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no  (设置是否允许X11转发)
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PrintMotd yes  (设置sshd是否在用户登录的时候显示“/etc/motd”中的信息)
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10 (同时登录的用户的个数)
#PermitTunnel no
#ChrootDirectory none (ChrootDirectory /home/%u改变登陆者的目录)

# no default banner path
#Banner none

# override default of no subsystems
Subsystem  sftp  /usr/libexec/openssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#  X11Forwarding no
#  AllowTcpForwarding no
#  ForceCommand cvs server