⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1041.html

📁 著名的linux英雄站点的文档打包
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<br>
Linux程式设计- 3.signals <br>
http://www.openchess.org/noitatsko/programming/ (2001-05-24 16:47:48) <br>
信号处理 <br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
信号处理概说  <br>
送出信号  <br>
接收信号  <br>
信号的处理  <br>
任务控制  <br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
POSIX IPC  <br>
reliable/unreliable  <br>
reentrant  <br>
pending  <br>
sending signals  <br>
catching signals  <br>
manipulating  <br>
signal definitions  <br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
信号singals <br>
信号的处理可以用一大章来写,涉及的层面也会深入整个作业系统中,我并不打算这样做,因为您可能会越搞越迷糊。这里我只告诉您如何接上信号,在实用的层面上,这样便很够用了。您可以先利用这些基本的技巧来撰写程式,等到有进一步高等应用的需要时,找一本较深入的UNIX Programming教材,专门研究signal的写法。  <br>
一般简单的signal写法如下:  <br>
<br>
void mysignal(int signo)  <br>
{  <br>
  /* my signal handler */  <br>
}  <br>
<br>
void initsignal(void)  <br>
{  <br>
  struct sigaction act;  <br>
<br>
  act.sa_handler = mysignal;  <br>
  act.sa_flags   = 0;  <br>
  sigemptyset(&act.sa_mask);  <br>
  sigaction(SIGHUP,&act,NULL);  <br>
  sigaction(SIGINT,&act,NULL);  <br>
  sigaction(SIGQUIT,&act,NULL);  <br>
  sigaction(SIGILL,&act,NULL);  <br>
  sigaction(SIGTERM,&act,NULL);  <br>
}  <br>
   <br>
<br>
例一: lock.c <br>
在fork的例三中提到,在daemon被杀掉时,需要在离开前,将/var/run/lock.pid删除。这里我们可以利用signal来处理这件事。  <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
<br>
#define LOCK_FILE "/var/run/lock.pid"  <br>
<br>
void quit(int signo)  <br>
{  <br>
  printf("Receive signal %d",signo);  <br>
  unlink(LOCK_FILE);  <br>
  exit(1);  <br>
}  <br>
<br>
void main(void)  <br>
{  <br>
  FILE *fp;  <br>
  pid_t pid;  <br>
  struct sigaction act;  <br>
<br>
  if (access(LOCK_FILE,R_OK)==0) {  <br>
    printf("Existing a copy of this daemon!");  <br>
    exit(1);  <br>
  }  <br>
<br>
  pid = fork();  <br>
<br>
  if (pid&gt;0) {  <br>
    printf("daemon on duty!");  <br>
<br>
    fp = fopen(LOCK_FILE,"wt");  <br>
    fprintf(fp,"%d",pid);  <br>
    fclose(fp);  <br>
  } else  <br>
    exit(0);  if (pid&lt;0) {  <br>
    printf("Can't fork!");  <br>
    exit(-1);  <br>
  }  <br>
<br>
  act.sa_handler = quit;  <br>
  act.sa_flags   = 0;  <br>
  sigemptyset(&act.sa_mask);  <br>
  sigaction(SIGTERM,&act,NULL);  <br>
  sigaction(SIGHUP,&act,NULL);  <br>
  sigaction(SIGINT,&act,NULL);  <br>
  sigaction(SIGQUIT,&act,NULL);  <br>
  sigaction(SIGUSR1,&act,NULL);  <br>
  sigaction(SIGUSR2,&act,NULL);  <br>
<br>
  for (;;) {  <br>
    sleep(3);  <br>
  }  <br>
}  <br>
<br>
编译: <br>
gcc -o ex1 lock.c  <br>
执行 <br>
./ex1  <br>
daemon on duty!  <br>
<br>
送信号 <br>
我们先找出该守护神程式的pid  <br>
PID=`cat /var/run/lock.pid`  <br>
<br>
接下来利用kill来送信号  <br>
<br>
kill $PID  <br>
<br>
Receive signal 15  <br>
<br>
程式将会结束,并且/var/run/lock.pid将会被删除掉,以便下一次daemon再启动。注意到如果quit函数内,没有放exit(),程式将永远杀不掉。  <br>
<br>
接下来送一些其它的信号试试看。  <br>
./ex1  <br>
PID=`cat /var/run/lock.pid`  <br>
kill -HUP $PID  <br>
<br>
Receive signal 1  <br>
<br>
您可以自行试试  <br>
kill -INT $PID  <br>
kill -QUIT $PID  <br>
kill -ILL $PID  <br>
.  <br>
.  <br>
.  <br>
等等这些信号,看看他们的结果如何。  <br>
<br>
信号的定义 <br>
在/usr/include/signum.h中有各种信号的定义  <br>
#define SIGHUP          1 &nb  <br>
 <br>
 <br>
Linux程式设计- 4.socket <br>
http://www.openchess.org/noitatsko/programming/ (2001-05-24 17:24:26) <br>
UNIX Socket Programming基本上是一本书名。Socket programming其实需要相当程度的基础,我不想在这包山包海地,如果您需要彻底研究,可以买这本书来看。在此我想提供一些简单的Server/Client两端的简单写法,让你有个起点,做为进一步研究的基础。很多涉及较复杂的内容的,我在这便不详细说明,您可以照本宣科,照抄着用,稍微熟悉时,再细细研究。  <br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
Client <br>
int sock_connect(char *domain,int port)  <br>
{  <br>
  int white_sock;  <br>
  struct hostent * site;  <br>
  struct sockaddr_in me;  <br>
  site = gethostbyname(domain);  <br>
  if (site==NULL) return -2;  <br>
<br>
  white_sock = socket(AF_INET,SOCK_STREAM,0);  <br>
  if (white_sock&lt;0) return -1;  <br>
<br>
  memset(&me,0,sizeof(struct sockaddr_in));  <br>
  memcpy(&me.sin_addr,site-&gt;h_addr_list[0],site-&gt;h_length);  <br>
  me.sin_family = AF_INET;  <br>
  me.sin_port = htons(port);  <br>
<br>
  return (connect(white_sock,(struct sockaddr *)&me,sizeof(struct sockaddr))&lt;0) ? -1 : white_sock;  <br>
}  <br>
<br>
要由Client向伺服器端要求连线的步骤,首先您必须要找出对方的位址,可利用:  <br>
<br>
gethostbyname()  <br>
<br>
接下来要建立起一个socket,然後用这个socket来建立连线。  <br>
<br>
接下来我们利用这个简单的socket程式来写一个读取WWW网页的简单浏览器(看html source)。  <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
<br>
int htconnect(char *domain,int port)  <br>
{  <br>
  int white_sock;  <br>
  struct hostent * site;  <br>
  struct sockaddr_in me;  <br>
<br>
  site = gethostbyname(domain);  <br>
  if (site==NULL) return -2;  <br>
   <br>
<br>
  white_sock = socket(AF_INET,SOCK_STREAM,0);  <br>
  if (white_sock&lt;0) return -1;  <br>
<br>
  memset(&me,0,sizeof(struct sockaddr_in));  <br>
  memcpy(&me.sin_addr,site-&gt;h_addr_list[0],site-&gt;h_length);  <br>
  me.sin_family = AF_INET;  <br>
  me.sin_port = htons(port);  <br>
<br>
  return (connect(white_sock,(struct sockaddr *)&me,sizeof(struct sockaddr))&lt;0) ? -1 : white_sock;  <br>
}  <br>
<br>
int htsend(int sock,char *fmt,...)  <br>
{  <br>
  char BUF[1024];  <br>
  va_list argptr;  <br>
  va_start(argptr,fmt);  <br>
  vsprintf(BUF,fmt,argptr);  <br>
  va_end(argptr);  <br>
  return send(sock,BUF,strlen(BUF),0);  <br>
}  <br>
<br>
void main(int argc,char **argv)  <br>
{  <br>
  int black_sock;  <br>
  char bugs_bunny[3];  <br>
<br>
  if (argc&lt;2) return;  <br>
<br>
  black_sock = htconnect(argv[1],80);  <br>
  if (black_sock&lt;0) return;  <br>
  htsend(black_sock,"GET / HTTP/1.0%c",10);  <br>
  htsend(black_sock,"Host: %s%c",argv[1],10);  <br>
  htsend(black_sock,"%c",10);  <br>
  while (read(black_sock,bugs_bunny,1)&gt;0) { printf("%c",bugs_bunny[0]); }  <br>
<br>
  close(black_sock);  <br>
}  <br>
<br>
编译: <br>
gcc -o ex1 client.c  <br>
执行 <br>
./ex1 www.linux.org.tw  <br>
<br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
Server <br>
Listen to a port <br>
要建立起一个网路伺服器,第一步就是要"倾远方",也就是要Listen。  <br>
以下是一般建立服务的方法:  <br>
int DaemonSocket;  <br>
struct sockaddr_in DaemonAddr;  <br>
int BindSocket(void)  <br>
{  <br>
<br>
  DaemonSocket = socket(AF_INET,SOCK_STREAM,0);  <br>
  if (DaemonSocket==-1) return 0;  <br>
  DaemonAddr.sin_family = AF_INET;  <br>
  DaemonAddr.sin_port   = htons(DAEMON_PORT);  <br>
  if (bind(DaemonSocket,&DaemonAddr,sizeof(DaemonAddr))&lt;0) {  <br>
    printf("Can not bind!");  <br>
    return 0;  <br>
  }  <br>
  if (listen(DaemonSocket,1024)!=0) {  <br>
    printf("Can not listen!");  <br>
    return 0;  <br>
  }  <br>
<br>
  return 1;  <br>
}  <br>
<br>
Incoming call <br>
要查看是否有连线进来,可用以下方式:  <br>
int incoming_call(void)  <br>
{  <br>
  fd_set sock;  <br>
  struct timeval tv;  <br>
  int t;  <br>
<br>
  FD_ZERO(&sock);  <br>
  FD_SET(DaemonSocket,&sock);  <br>
  tv.tv_sec = 60; tv.tv_usec = 0;  <br>
  t = select(DaemonSocket + 1,&sock,NULL,NULL,&tv);  <br>
  if (t&lt;=0||!FD_ISSET(DaemonSocket,&sock)) return 0;  <br>
<br>
  printf("incoming...");  <br>
<br>
  return 1;  <br>
}  <br>
<br>
Connect Client <br>
当我们确认有人进来要求服务时,会需要accept connection,可用以下方式  <br>
int ConnectClient(void)  <br>
{  <br>
  int socksize=sizeof(HostAddr);  <br>
  unsigned char * addr;  <br>
<br>
  ClientSocket = accept(DaemonSocket,(struct sockaddr*)&HostAddr,&socksize);  <br>
  if (ClientSocket&lt;0) return 0;  <br>
<br>
  addr = (unsigned char *)&HostAddr.sin_addr.s_addr;  <br>
<br>
  printf("incoming address:%d.%d.%d.%d",addr[0],addr[1],addr[2],addr[3]);  <br>
<br>
  return 1;  <br>
}  <br>
<br>
注意到当您accept connection之後,连线已建立起,此时要用的socket是ClientSocket,而非DaemonSocket,ClientSocket才是真正用来连线用的socket。  <br>
<br>
这是个我才刚开始动手写的象棋伺服器。  <br>
<br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>
#include   <br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -