TCP--server升級版

前面已經編寫完基本的TCP服務器和客戶端了;現在要對服務器做一個改進版本的,前面的服務器,其實只支持一個訪問,因爲當我們監聽到一個程序的時候,本進程只能服務其一個socket;
現在來寫一個支持多用戶訪問的,其中有好幾個方法,可以來支持多用戶訪問;

  1. 可以使用多進程,每當監聽到一個請求時,就創建一個進程來讓子進程去爲他服務;這樣就可以再去監聽下一個請求了;
 53         int id = fork();
 54         if(id < 0 )
 55         {
 56             printf("fork  error!\n");
 57             exit(5);
 58         }
 59         else if(id == 0)
 60         {//子進程來處理
 61 
 62             while(1)
 63             {
 64                 int id = fork();
 65                 if(id > 0 )//偷懶行爲,再創建一次,父進程退出,這樣就成孤兒進程在處理,最後由init進程管理
 66                 {
 67                     exit(0);
 68                 }
 69                 char buf[1024];                                                                                                                                     
 70                 ssize_t s = read(client_sock,buf,sizeof(buf));
 71                 if(s>0)
 72                 {
 73                     buf[s] = 0;
 74                     printf("client :# %s\n",buf);
 75                 }
 76                 else
 77                 {
 78                     printf("read down ..........break;");
 79                     break;
 80                 }
 81                 write(client_sock,buf,sizeof(buf)-1);
 82             }
 83         }
 84         else
 85         {
 86 
 87         }

這個樣子就實現了多進程的處理的;

2.同時也就有相應的多線程的版本,其實原理都是一樣的,監聽到了就拿出去創建一個新的線程來處理它就好了;
把處理請求邏輯拿出來封裝爲一個函數;

 11 void* handlerRequest(void* arg)
 12 {
 13     int new_fd = (int)arg;
 14     while(1)
 15     {
 16         char buf[1024];
 17         ssize_t s= read(new_fd,buf,sizeof(buf)-1);
 18         if(s > 0)
 19         {
 20             buf[s] = 0;
 21             printf("client:%s\n",buf);
 22             write(new_fd,buf,strlen(buf));
 23         }
 24         else
 25         {
 26             printf("read done....\n");
 27             break;
 28         }                                                                                                                                                           
 29     }
 30 }

然後再在接到請求的時候創建線程就好了;

 75         pthread_t id;
 76         pthread_create(&id,NULL,handlerRequest,(void*)client_sock);
 77         pthread_detach(id);

這樣就可以了;

這裏還要研究一個問題就是,TCP連接中當我們最後申請斷開的一方是要進入TIME_WAIT狀態的,這個時候,如果是我們編寫的代碼的話,服務器自己斷開的,再重啓就要進入TIME_WAIT,這對現實中it公司可以大問題,服務器掛掉起不起來;
這裏寫圖片描述

所以就有了一個解決方案,使⽤setsockopt()設置socket描述符的 選項SO_REUSEADDR爲1,表⽰允許創建端⼜號相同但IP地址不同的多個socket描述符。
setsockopt

opt

這個樣子就好了,如果是服務器掛掉也可以立即重啓了;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章