(三十八)会话Session
说起会话,我们经常登录到linux系统,执行各种各样的程序,这都牵涉到会话。但是,一般情况下我们又很少会去关注到会话的存在,很少会去了解它的来龙去脉。 维系一个会话,最常见的有两种方式: 一是基于某种凭证,比如web网站的登录会话,在登录验证之后,服务器就会返回一个session id作为凭证。用户之后的请求总是会带上这个id,而服务器通过这个id也就能知道用户是谁。直到用户注销
说起会话,我们经常登录到linux系统,执行各种各样的程序,这都牵涉到会话。但是,一般情况下我们又很少会去关注到会话的存在,很少会去了解它的来龙去脉。
维系一个会话,最常见的有两种方式:
一是基于某种凭证,比如web网站的登录会话,在登录验证之后,服务器就会返回一个session id作为凭证。用户之后的请求总是会带上这个id,而服务器通过这个id也就能知道用户是谁。直到用户注销登录、或者登录超时,服务器会清洗掉对应的session id,这个id就失效了,会话也就随之而结束。
第二种方式是基于连接的,当用户和系统之间的连接启用时,系统会对用户进行验证,验证通过之后,来自这个连接的操作都是属于这个用户的。直到连接断开,则会话结束。
linux系统的会话就是以第二种方式来维系的。会话基于连接,那么连接的安全性就决定了会话的安全性。以最常见的两种连接为例:
1、本地连接,用户是直接通过键盘显示器来跟系统交互的,键盘显示器直接连接在主机上,连接被篡改基本上是不可能的;
2、远程连接,以ssh为例,其协议会进行加密,从而避免连接被篡改;
调用以下函数可以使进程成为会话组长:
pid_t setsid(void)
要注意的是:
1.调用进程不能是进程组组长,该进程变成新会话首进程(session header)
2.该进程成为一个新进程组的组长进程。
3.需有root权限(ubuntu不需要)
4.新会话丢弃原有的控制终端,该会话没有控制终端
5.该调用进程是组长进程,则出错返回
6.建立新会话时,先调用fork, 父进程终止,子进程调用
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
if ((pid = fork())<0) {
perror("fork");
exit(1);
} else if (pid == 0) {
printf("child process PID is %d\n", getpid());
printf("Group ID of child is %d\n", getpgid(0));
printf("Session ID of child is %d\n", getsid(0));
sleep(10);
setsid(); // 子进程非组长进程,故其成为新会话首进程,且成为组长进程。该进程组id即为会话进程
printf("Changed:\n");
printf("child process PID is %d\n", getpid());
printf("Group ID of child is %d\n", getpgid(0));
printf("Session ID of child is %d\n", getsid(0));
sleep(20);
exit(0);
}
return 0;
}
输出结果:
child process PID is 3978
Group ID of child is 3977
Session ID of child is 3305
Changed:
child process PID is 3978
Group ID of child is 3978
Session ID of child is 3978
通过以下函数查看会话进程ID
pid_t getsid(pid_t pid)
pid为0表示察看当前进程session ID
注:组长进程不能成为新会话首进程,新会话首进程必定会成为组长进程。
更多推荐
所有评论(0)