关于linux 编程

zhanglc_love 2009-04-22 07:50:23
最近要做这个实验,但是无从下手 希望各位能帮帮我 要尽快给我恢复 我很急用 高分请教!!
若有代码 请发到我的邮箱 wszlc_love@163.com 谢谢


实验二 多进程编程
一、实验目的
1、理解进程的基本概念和基本的进程函数。
2、学习网络编程的基本操作和设计原则。
3、掌握客户/服务器协议。
4、服务器设计:使用fork来接收多个请求。
5、如何解决僵尸(zombie)问题。
二、实验类型
设计型。
三、预习内容
预习课本有关进程和Socket等相关内容。
四、实验内容与提示
1、三个主要操作
客户和服务器都是进程。服务器设立服务,然后进入循环接收和处理请求。客户连接到服务器,然后发送、接受或者交换数据,最后退出。该交互过程中主要包含了一下3个操作:
服务器设立服务。
客户连接到服务器。
服务器和客户处理事务。
(1)操作1:建立服务器端socket
首先,如下所示,描述了服务器设立一个服务的过程。设立一个服务一般需要如下3个步骤:
i .创建一个socket
socket = socket(AF_INET, SOCK_STREAM,0)
ii.给socket绑定一个地址
bind(sock,&addr,sizeof(addr))
iii.监听接入请求
listen(sock,queue_size)
为了避免在编写服务器时重复输入上述代码,将这3个步骤组合成一个函数:make_server_socke。在编写服务器的程序时候,只要调用该函数就可以创建一个服务器端socket。具体如下:
sock = make_server_socket(int portnum)
return -1 if error,
or a server socket listening at port “portnum”
(2)建立到服务器的连接
其次,将客户连接到服务器。如下所示,基于流的网络客户连接到服务器包含以下连个步骤:
i.创建和一个socket
socket = socket(AF_INET, SOCK_STREAM,0)
ii.使用该socket连接到服务器
connect(sock,&serv_addr,sizeof(serv_addr))
将这两个步骤抽象成一个函数:connet_to_server。当编写客户端程序时,只要调用该函数就可以建立到服务器的连接。具体如下:
fd = connect_to_server(hostname,portnum)
return -1 if error,
or a fd open for reading and writing connected to the socket at port “portnum” on host “hostname”
(3)操作3:客户/服务器的会话
至此,可以使用专门的函数来建立服务器的socket,同时也有专门的函数来连接到服务器。在实践中,如何利用上述函数呢?客户和服务器之间的交互内容又是什么呢?下面给出客户端程序和服务器程序编写的一般形式,以及一些建立服务器的设计方案。
i.一般的客户端
网络客户通常调用服务器来获得服务,一个典型的客户程序如下:
main()
{
int fd;
fd = connect_to_server(host); /*call the server*/
if(fd == -1)
exit(1); /*or die*/
talk_with_server(fd); /*chat with server*/
close(fd);
}
函数talk_with_server处理与服务器的会话。具体的内容取决于特定应用。例如,e-mail客户和邮件服务器交谈的是邮件,而天气预报客户和服务器交谈的则是天气。
ii.一般的服务器端
一个典型的服务器如下:
main()
{
int sock,fd; /*socket and connection*/
sock = make_server_socket(port);
if(sock == -1)
exit(1);
while(1)
{
fd = accept(sock, NULL,NULL); /*take next call*/
if(fd==-1)
break; /*or die*/
process_request(fd); /*chat with client*/
close(fd); /*hang up when done*/
}
}
函数process_request处理客户的请求。具体的内容取决于特定应用。例如,邮件服务器告诉客户信件信息,天气服务器则告诉客户天气情况。
2、服务器的设计问题:DIY或代理
这里使用了两种服务器的设计方法:
自己做(Do It Yourself ,DIY) ------服务器接收请求,自己处理工作。
代理------服务器接收请求,然后创建一个新进程来处理工作。
每种方法的优缺点各是什么?
自己做用于快速简单的任务
代理用于慢速的更加复杂的任务
使用SIGCHLD来阻止僵尸问题
除了等待子进程死亡外,父进程可以设置为接收表示子进程死亡的信号。当子进程退出或被终止时,内核发送SIGCHLD给父进程。父进程可以为SIGCHLD设置一个信号处理函数,它可以调用wait。具体方法如下:
/*naïve use of SIGCHLD handler with wait() -buggy*/
main()
{
int sock, fd;
void child_waiter(int),process_request(int);
signal(SIGCHLD,child_waiter);
if((sock=make_server_socket(PORTNUM))== -1)
oops(“make_server_socket”);
while(1){
fd = accept(sock,NULL,NULL);
if(fd == -1)
break;
process_request(fd);
close(fd);
}
}


void child_waiter(int signum)
{
wait(NULL);
}

3、Web服务器功能
Web服务器通常要具有3种用户操作:
列举目录信息
cat文件
运行程序

Web服务器通过基于流的socket连接为客户提供了上述3中操作。如上图所示,用户连接到服务器后,发送请求,然后服务器返回客户请求的信息。具体过程如下:
客户端: 服务器端:
用户选择一个链接
连接服务器 --- 接收请求
写请求 --- 读取请求
处理请求:
目录:显示目录列表
文件:显示内容
.cgi文件:运行
不存在:错误信息
读取应答 --- 写应答
挂断
显示应答
html:解析
image:绘图
sound:运行
重复
4、Web服务器协议
客户端(浏览器)与Web服务器之间的交互主要包含客户的请求和服务器的应答。请求和应答的格式在超文本传输协议(HTTP)中有定义。HTTP使用纯文本。可以使用telnet和Web服务器进行交互。Web服务器在端口80监听。下面是一个实际例子:
$telnet www.prenhall.com 80
Trying 165.193.123.253…
Connected to www.prenhall.com.
Escape character is ‘^]’
GET /index.html HTTP/1.0

HTTP/1.1 200 OK
Server:Netscape-Enterprise/3.6 SP3
Date:Tue, 22 Jan 2002 16:11:14 GMT
Content-type: text/html
Last – modified : Fri, 08 Sep 2000 20:20:06 GMT
Content – length: 327
Accept – ranges: bytes
Connection: close
<HTML><HEAD>
<META HTTP-EQUIV = “Refresh”CONTENT=”0;
URL = http://vig.prenhall.com/”>
</HEAD><BODY></BODY></HTML>
<!------------------------------------------------------------------------------------------->
<!-- Caught you peeking! -- -->
<!--------------------------------------------------------------------------------------------->
Connection closed by foreign host.
$
这里只发送了一行请求,却接收了多行返回。细节如下:
(1)HTTP请求:GET
telnet创建了一个socket并调用了connect来连接到Web服务器。服务器接受连接请求,并创建了一个基于socket的从客户端的键盘到Web服务器进程的数据通道。
接下来,输入请求:
GET /index.html HTTP/1.0
一个HTTP请求包含有3个字符串。第一个字符串是命令,第二个是参数,第三个是所用协议的版本号。在该例中,使用了GET命令,以index.html作为参数,使用了HTTP版本1.0 。实际上,一个Web服务器只是集成了cat和ls的Unix shell。
(2)HTTP应答:OK
服务器读取请求,检查请求,然后返回一个应答。应答有两个部分:头部和内容。头部以状态行起始,如下所示:
HTTP/1.1 200 OK
状态行含有两个或更多的字符串。第一个串是协议的版本,第二个串是返回码,这里是200,其文本的解释是OK。这里请求的文件叫/index.html,而服务器给出应答表示可以得到该文件。如果服务器中没有所请求的文件名,返回码将是404,其解释将是“未找到”。
头部的其余部分是关于应答的附加信息。在该例子中,附加信息包含服务器名、应答时间、服务器所发送数据类型以及应答的连接类型。一个应答头部可以包含有多行信息,以空行表示结束,空行位于Connection:close后面。
应答的其余部分是返回的具体内容。这里,服务器返回了文件/index.html的内容。
5、编写Web服务器
要求Web服务器只支持GET命令,只接收请求行,跳过其余参数,然后处理请求和发送应答,主要循环如下:
while(1)
{
fd=accept(sock,NULL,NULL); /*take a call*/
fpin=fdopen(fd, “r”); /*make it a FILE*/
fgets(fpin, reques, LEN); /*read client request*/
read_until_crnl(fpin); /*skip over arguments*/
process_rq(request,fd); /*hang up connection*/
}
为了简洁起见,这里忽略了出错检查。
(1)处理请求
处理请求包含识别命令和根据参数进行处理:
process_rq(char *rq , int fd )
{
char cmd[11], arg[513];
if(fork( )!=0) /*if a child ,do work*/
return;
sscanf(rq, “%10s%512s”,cmd, arg);
if(strcmp(cmd, “GET”)!=0) /*check command*/
cannot_do(fd);
else if (not_exist(arg)) /*does the arg exist*/
do_404(arg,fd); /*n:tell the user*/
else if (isadir(arg)) /*is it a directory?*/
do_ls(arg,fd); /*y:list contents*/
else if(ends_in_cgi(arg)) /*name is X.cgi?*/
do_exec(arg,fd); /*y: execute it*/
else /*otherwise*/
do_cat(arg,fd); /*display contents*/
}
服务器为每个请求创建一个新的进程来处理。子进程将请求分割成命令和参数。如果命令不是GET,服务器应答HTTP返回码表示未实现的命令。如果命令是GET,服务器将期望得到目录名,一个以.cgi结尾的可执行程序或文件名。如果没有该目录或指定的文件名,服务器报错。
如果存在目录或文件,服务器决定所要使用的操作:ls、exex或cat。
(2)目录列表函数
函数do_ls处理列出目录信息的请求:
do_ls(char *dir, int fd)
{
FILE *fp;
fp = fdopen(fd,”w”);
header(fp, “text/plain”);
fprintf(fp, “fp,”\r\n””);
fflush(fp);

dup2(fd,1);
dup2(fd,2);
close(fd);
execl(“/bin/ls”,”ls”,”-l”,dir,NULL);
perror(dir);
exit(1);
}
(3)其他函数:
程序可以工作,但它并不完整,也不安全,需要做如下的改进:
(1)僵尸进程的去除;
(2)缓存溢出保护;
(3)CGI(Common Gateway Interface,通用网关接口)程序需要设置一些环境变量;
(4)HTTP头部可以包含更多的信息。
6、测试(运行Web服务器)
编译程序,在某个端口运行它:
$cc webserv.c socklib.c –o webserv
$./webserv 12345
现在可以访问Web服务器,网址为http://yourhostname:12345/。将html文件放到该目录中并且用http://yourhostname:12345//filename.html来打开它。创建下面的shell脚本:
#!/bin/sh
#hello.cgi-a cheery cgi page
Printf “Content-type/plain\n\nhello\n”;
将它命名为hello.cgi,用chmod改变权限755,然后用浏览器调用该程序:http://yourhostname:12345/hello.cgi。
...全文
171 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
solele 2011-11-21
  • 打赏
  • 举报
回复
哈哈 笑死我了
star598388532 2010-05-04
  • 打赏
  • 举报
回复
wangxueyi老师飘过~我回关注你的~作业自己作哦!
xiuzhaoyang 2010-03-17
  • 打赏
  • 举报
回复
!!!!!!!!!!!!!!!!!!!!!!!!!!!!

23,114

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧