基於libnids的TCP數據流的還原(多線程實現)

 我們知道,libnids本身可以實現TCP數據流的重組,但是如果一個TCP流數據量比較大的時候,就會分成好多個TCP報文段,這些報文段在網絡中的傳播可能是亂序的,利用libnids可以幫助我們按順序接收到這些報文段,即實現TCP報文段的重組。

    但是我們如何把這些順序的報文段重新還原成一個完整的數據文件,也是要考慮的一個問題,因爲在很多時候,單個的報文段對我們的意義不大,我們需要一個完整的數據,這樣才有助於我們進一步分析網絡中的數據內容。

    下面的程序實現了基於libnids的TCP數據流的還原,我使用了多線程來控制數據的處理,主要的數據結構是一個帶頭結點的雙向鏈表隊列,隊列中的每個結點存儲一個完整的TCP數據流的內容,另外還有兩個元素,分別是指向前導和後續結點的結構體指針。結構體定義如下:

    struct buf{

        char *buffer;

        struct buf *prev;

        struct buf *next;

    };

    頭結點:  struct buf *head;

    多線程對該鏈表的操作:

    向鏈表中放數據:void put_function(int size, char *data)

                    {

                          pthread_mutex_lock(&mutex);

                          meke_new_item(size, data);

                          buffer_has_item++;

                          pthread_mutex_unlock(&mutex);

                          sleep(1);

                    }

    mutex爲互斥鎖,size爲data的大小,data爲完整的數據流,buffer_has_item爲當前鏈表中結點的數目。

    從鏈表中去數據的操作:(這是一個線程函數,在執行pthread_create是創建)

    void get_function(void)

    {

          while(1){

                  pthread_mutex_lock(&mutex);

                  if(buffer_has_item > 0){

                           consume_item();

                           buffer_has_item--;

                  }

                  pthread_mutex_unlock(&mutex);

                  sleep(1);

          }

    }

    創建新的節點並把它掛到隊列當中:

    void make_new_item(int size, char *data)

    {

          struct buf *con;

          if(!(con = (struct buf *)malloc(sizeof(struct buf)))){

                 assert("con malloc fail!");

          }

          if(!(con->buffer = (char *)malloc(size*sizeof(char)))){

                  assert("con buffer malloc fail!");

          }

          memset(con->buffer, 0, size*sizeof(char));

          memcpy(con->buffer, data, size*sizeof(char));

          con->prev = NULL;

          con->next = NULL;

          if(head->next == NULL){

                head->next = con;

                head->prev = con;

                con->prev = head;

          }else{

                con->prev = head->prev;

                head->prev->next = con;

                head->prev = con;

                con->next = NULL;

          }

     }

     處理還原之後的數據:

     void consume_item()

     {

          int k;

          struct buf *p;

          if(head->next){

                

                 printf("%s", head->next->buffer);

                 p = head->next;

                 if(head->next->next){

                       head->next = head->next->next;

                       head->next->preb = head;

                 }else{

                        head->next = NULL;

                        head->prev = NULL;

                  }

                  if(p){

                        free(p);

                        p = NULL;

                   }

           }

     }

     鏈表初始化(可以把整個程序的初始化都放在這裏進行):

     void init_dlink()

     {

           if(!(head = (struct buf *)malloc(sizeof(struct buf)))){

                     assert("head malloc fail!");

            }

            head->next = NULL;

            head->prev = NULL;

      }

      head的定義是一個全局變量,struct buf *head;

      在主函數當中,要創建線程,註冊libnids回調函數:

      int main(int argc, char *argc[])

      {

            pthread_t thread;

            init_dlink();

            pthread_mutex_init(&mutex, NULL);

            if(!nids_init())P{

                  assert("nids init fail!");

            }

            pthread_create(&thread, NULL, (void *)get_function, NULL);

            nids_register_tcp(tcp_protocol_callback);

            nids_tun();

            return 0;

       }

       在回調函數當中,我們可以組織實現TCP數據流的還原,並把還原之後的數據添加到鏈表當中:

       void tcp_protocol_callback(struct tcp_stream *tcp_connection, void **arg)

       {

            switch(tcp_connection->nids_state){

                   .....................

                   case NIDS_DATA:{

                         ................

                         if(tcp_connection->client.count_new){

                               

                                ..............

                               

                                put_function(sum_len, content);

                         }

                   }

            }

        }

    至此,就完成了還原TCP數據流的多線程處理。

發佈了0 篇原創文章 · 獲贊 1 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章