记下servfox中的一些问题及网上分析

首先server.c中如下几行代码:

signal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */

sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;

 

/***********************************************************/

      当服务器close一个连接时,若client端接着发数据。 根据TCP协议的规定,会

收到一个RST响应,client再向这个服务器发送数据时系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。
    根据信号的默认处理规则SIGPIPE默认执行动作是terminate(终止、退出),所以client会退出。若不想客户端退出,可以把SIGPIPE设为SIG_IGN,如

signal(SIGPIPE,SIG_IGN);这时SIGPIPE交给了系统处理。
   服务器采用了fork的话,要收集垃圾进程,防止僵尸进程的产生。可以这样处理。
signal(SIGCHLD, SIG_IGN);交给系统init去回收。
   这里子进程就不会产生僵尸进程了。

 

 

/****************************************************************/

 

       sigaction()是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非 POSIX系统上运行,那么就应该使用这个接口)
       给信号signum设置新的信号处理函数act, 同时保留该信号原有的信号处理函数oldact
------------------------------------------------
    int sigaction(  int   signum, const struct
sigaction --*act,

                        struct sigaction *oldact)


#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void show_handler(int sig)
     {
        printf("I got signal %d/n", sig);
        int i;
       for(i = 0; i < 5; i++)

          {
           printf("i = %d/n", i);
          sleep(1);
         }
    }

int main(void)
{
    int i = 0;
    struct sigaction act, oldact;
    act.sa_handler = show_handler;
    sigaddset(&act.sa_mask, SIGQUIT); //(1)
    act.sa_flags = SA_RESETHAND | SA_NODEFER; //(2)
    //act.sa_flags = 0;                                          //(3)

    sigaction(SIGINT, &act, &oldact);
    while(1)

               {
                  sleep(1);
                   printf("sleeping %d/n", i);
                    i++;
             }
}

注:
(1)    如果在信号SIGINT(Ctrl + c)的信号处理函数show_handler执行过程中,本进程收到信号SIGQUIT(Crt+/),将阻塞该信号,直到show_handler执行结束才会处理信号SIGQUIT。
(2)    SA_NODEFER       一般情况下, 当信号处理函数运行时,内核将阻塞<该给定信号 -- SIGINT>。但是如果设置了SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号。 SA_NODEFER是这个标记的正式的POSIX名字(还有一个名字SA_NOMASK,为了软件的可移植性,一般不用这个名字)   
       SA_RESETHAND    当调用信号处理函数时,将信号的处理函数重置为缺省值。 SA_RESETHAND是这个标记的正式的POSIX名字(还有一个名字SA_ONESHOT,为了软件的可移植性,一般不用这个名字)   
(3)    如果不需要重置该给定信号的处理函数为缺省值;并且不需要阻塞该给定信号(无须设置sa_flags标志),那么必须将sa_flags清零,否则运行将会产生段错误。但是sa_flags清零后可能会造成信号丢失!


 

 

 

/*****************************************************************/

在SPCAV4L.C文件中:

jpegsize= convertframe(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t),
vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame],
 vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn);

headerframe=(struct frame_t*)vd->ptframe[vd->frame_cour];

刚开始看的一头雾水,原来结构体frame_t是用来保存控制视频图像的相关信息,convertframe()函数将pFramebuffer中的数据转成完整的JPEG格式的数据保存到ptframe缓存中去,在frame_t指向的地址后面,紧接着的是转换成JPEG格式后的数据,

在SOCKET中,是先写入frame_t,再写入jpeg数据。

ret = write_sock(sock, (unsigned char *)headerframe, sizeof(struct frame_t)) ;

if(!wakeup)
ret = write_sock(sock,(unsigned char*)(videoIn.ptframe[frameout]+sizeof(struct frame_t)),headerframe->size);

 

 

 

 

/*************************************************************/

下面是百度找到的,关于字符指针转换成结构体指针的说法:

我这里有这样的结构体
struct roadmap_db_section {
   char name[12];
   int  first;
   int  next;
   int  size;
   int  count; 
};
然后有这样一条语句: char * c = &ss(其中ss为一个文件内容在内存中的首地址)
struct* s = (struct roadmap_db_section *) c;
我想问的是,这个字符型的指针,怎么就能强制转化为结构体类型的指针呢?转换
后这个结构体指针和字符指针之间是什么关系啊? 
指针说白了就是地址,32位机中地址是用long表示的,所以指针是可以相互转换的,
只是转换后寻址方式不同了而已.
上面的roadmap_db_section的在内存中占28字节,转成char*就相当于一个
char c[28], 不管它怎么换也就是这28个字节的内容.再转结构体时,前面12个
字节放入name[12]中,后面的每四位作一个整数 

你可能感兴趣的:(问题)