記下servfox中的一些問題及網上分析

weixin_33816946發表於2010-05-27

首先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]中,後面的每四位作一個整數 

相關文章