当前位置: 技术问答>linux和unix
关于通信的问题!
来源: 互联网 发布时间:2014-12-02
本文导语: 客户与服务器通信例子: $/etc/mknod Public p $chmod 664 Public 文件comm.h: #define PUBLIC "Public" //定义公共命名管道名称; struct message { char pipe[20]; //私有命名管道名称 char filename[256]; //检...
客户与服务器通信例子:
$/etc/mknod Public p
$chmod 664 Public
文件comm.h:
#define PUBLIC "Public" //定义公共命名管道名称;
struct message
{
char pipe[20]; //私有命名管道名称
char filename[256]; //检索文件名称
}
文件client.c:
#include
#include
#include
#include"comm.h" //这是一个头文件
mian(argc,argv)
int argc;
char *argv[];
{
int pubfd,prifd;
char buffer[256];
int num;
struct message mesg;
# 客户程序以请求的文件名作为参数
if (argc!=2)
{
fprintf(stderr,"Usage:client[filename]n");
exit(1);
}
#创建私有命名管道,管道名称为“private”
strcpy(mesg.pipe."Private");
if (mknod(mesg.pipe,S_IFIFO|0666,0)==-1)
{
perror("mknod");
exit(1);
}
#客户以只写方式打开公共命名管道
if (pubfd=open(PUBLIC,O_WRONLY)==-1)
{
perror("open");
exit(2);
}
#将客户创建的私有命名管道名称和检索文件名称写到公共命名管道中
strcpy(mesg.filename,argv[1]);
write(pubfd,&mesg,sizeof(mesg));
if (prifd=open(PRIVATE,O_RDONLY)==-1)
{
perror("open");
exit(2);
}
#从私有命名管道中读取服务器返回的数据
whlie((num=read(prifd,&buffer,sizeof(buffer)))>0)
write(1,buffer,num);
close(prifd);
close(pubfd);
unlink(mesg.pipe);
exit(0);
}
文件public.c:
#include
#include
#include"comm.h"
main(argc,argv)
int argc;
char *argv[];
{
int pubfd,prifd,fd;
char buffer[256];
int num;
#服务器以只读方式打开公共命名管道
if (pubfd=open(PUBLIC,O_RDONLY)==-1)
{
perror("open");
exit(2);
}
#服务器循环等待客户请求
while(1)
{
#读取客户请求的文件名称
if (read(pubfd,&mesg.sizeof(mesg))>0)
{
#打开文件
if (fd=open(mesg.filename,O_RDONLY)==-1)
{
perror("open");
exit(1);
}
#打开私有通道名称
if(prifd=open(mesg.pipe,O_WRONLY)==-1)
{
perror("open");
exit(1);
}
#从服务器文件中读取数据,并将读取的数据写到私有管道中,发给客户进程
while ((num=read(fd,buffer,sizeof(buffer))>0)
write(prifd,buffer,num);
close(fd);
close(prifd);
}
}
close(pubfd);
}
请问:
1。为什么主函数main的括弧中会有argc和argv?
2。在不同的地方用的exit(0),exit(1),exit(2)是什么作用?能不能互相替换?
3。谁如果有对这个程序有更好的理解,请你发表自己的看法。
$/etc/mknod Public p
$chmod 664 Public
文件comm.h:
#define PUBLIC "Public" //定义公共命名管道名称;
struct message
{
char pipe[20]; //私有命名管道名称
char filename[256]; //检索文件名称
}
文件client.c:
#include
#include
#include
#include"comm.h" //这是一个头文件
mian(argc,argv)
int argc;
char *argv[];
{
int pubfd,prifd;
char buffer[256];
int num;
struct message mesg;
# 客户程序以请求的文件名作为参数
if (argc!=2)
{
fprintf(stderr,"Usage:client[filename]n");
exit(1);
}
#创建私有命名管道,管道名称为“private”
strcpy(mesg.pipe."Private");
if (mknod(mesg.pipe,S_IFIFO|0666,0)==-1)
{
perror("mknod");
exit(1);
}
#客户以只写方式打开公共命名管道
if (pubfd=open(PUBLIC,O_WRONLY)==-1)
{
perror("open");
exit(2);
}
#将客户创建的私有命名管道名称和检索文件名称写到公共命名管道中
strcpy(mesg.filename,argv[1]);
write(pubfd,&mesg,sizeof(mesg));
if (prifd=open(PRIVATE,O_RDONLY)==-1)
{
perror("open");
exit(2);
}
#从私有命名管道中读取服务器返回的数据
whlie((num=read(prifd,&buffer,sizeof(buffer)))>0)
write(1,buffer,num);
close(prifd);
close(pubfd);
unlink(mesg.pipe);
exit(0);
}
文件public.c:
#include
#include
#include"comm.h"
main(argc,argv)
int argc;
char *argv[];
{
int pubfd,prifd,fd;
char buffer[256];
int num;
#服务器以只读方式打开公共命名管道
if (pubfd=open(PUBLIC,O_RDONLY)==-1)
{
perror("open");
exit(2);
}
#服务器循环等待客户请求
while(1)
{
#读取客户请求的文件名称
if (read(pubfd,&mesg.sizeof(mesg))>0)
{
#打开文件
if (fd=open(mesg.filename,O_RDONLY)==-1)
{
perror("open");
exit(1);
}
#打开私有通道名称
if(prifd=open(mesg.pipe,O_WRONLY)==-1)
{
perror("open");
exit(1);
}
#从服务器文件中读取数据,并将读取的数据写到私有管道中,发给客户进程
while ((num=read(fd,buffer,sizeof(buffer))>0)
write(prifd,buffer,num);
close(fd);
close(prifd);
}
}
close(pubfd);
}
请问:
1。为什么主函数main的括弧中会有argc和argv?
2。在不同的地方用的exit(0),exit(1),exit(2)是什么作用?能不能互相替换?
3。谁如果有对这个程序有更好的理解,请你发表自己的看法。
|
1接受参数呀。
2void exit(int status);
status:进程终止状态字。
2void exit(int status);
status:进程终止状态字。
|
1 main写错了
main中的参数表示你程序运行时命令行后面跟的参数。
我们可以根据参数来实现不同的运行方式,你这里的参数表示《检索文件名称》
2 一般情况下,0表示程序正常结束,而别的你可以自己定,具体的终止状态系统可能有规定,但是你可以不管。结束后,我们可以用echo $?看程序的终止状态.
main中的参数表示你程序运行时命令行后面跟的参数。
我们可以根据参数来实现不同的运行方式,你这里的参数表示《检索文件名称》
2 一般情况下,0表示程序正常结束,而别的你可以自己定,具体的终止状态系统可能有规定,但是你可以不管。结束后,我们可以用echo $?看程序的终止状态.
|
1 main中的参数表示你程序运行时命令行后面跟的参数。
argc: 参数个数
argv:参数内容
如program1 a b
则argc 为3
argv[0] program1 argv[1] a argv[2] b
2 exit(0)表示程序结束的返回值,用echo $?看程序的终止状态.
argc: 参数个数
argv:参数内容
如program1 a b
则argc 为3
argv[0] program1 argv[1] a argv[2] b
2 exit(0)表示程序结束的返回值,用echo $?看程序的终止状态.
|
1.argc是命令行参数的个数,argv[]中保存着你的命令行参数的值,如果一些参数要通过命令行来传递,则需要加argc,argv,如果没有,加上也不会报错。
2.exit()作用是退出程序,把控制权返回给操作系统。0,1,2只是传给系统的状态值,一般约定0是代表成功,一般非0代表失败。
3.这个程序就是客户端通过管道向服务端发出读文件的请求,服务端收到后,再通过管道把客户端请求的文件内容传递给客户端。
2.exit()作用是退出程序,把控制权返回给操作系统。0,1,2只是传给系统的状态值,一般约定0是代表成功,一般非0代表失败。
3.这个程序就是客户端通过管道向服务端发出读文件的请求,服务端收到后,再通过管道把客户端请求的文件内容传递给客户端。
|
main 全部参数是
int main(int argc, char * argv[], char * env[]);
前面大家已经说过啦,最后一个环境变量的
int main(int argc, char * argv[], char * env[]);
前面大家已经说过啦,最后一个环境变量的
|
完全不合理,不安全的服务器设计。
1.服务器不能因为一点小问题自己就退出了 ---- 到处是exit
2.非法客户端发过来的东西,很容易造成缓冲区溢出。只要发276个1过来,
if (fd=open(mesg.filename,O_RDONLY)==-1)
多半完蛋。
3.第一次发生的错误可能影响第二次请求。比如第一次发了277个字符过来,
服务器只接受276个,管道里多出来的一个字节,变成下一个请求的第一个字节,即使下一个请求合法,也不能正确执行。
4.私有管道名称由客户端分配也不合理,不可能避免重名。当然简单地由服务器分配也不行,服务器无法识别客户标识。去考虑用令牌方式吧。
哎,慢慢完善吧,这样的服务器也不是没有意义,至少可以给普通用户提供有限制的特权文件的访问。
1.服务器不能因为一点小问题自己就退出了 ---- 到处是exit
2.非法客户端发过来的东西,很容易造成缓冲区溢出。只要发276个1过来,
if (fd=open(mesg.filename,O_RDONLY)==-1)
多半完蛋。
3.第一次发生的错误可能影响第二次请求。比如第一次发了277个字符过来,
服务器只接受276个,管道里多出来的一个字节,变成下一个请求的第一个字节,即使下一个请求合法,也不能正确执行。
4.私有管道名称由客户端分配也不合理,不可能避免重名。当然简单地由服务器分配也不行,服务器无法识别客户标识。去考虑用令牌方式吧。
哎,慢慢完善吧,这样的服务器也不是没有意义,至少可以给普通用户提供有限制的特权文件的访问。