低成本服务解决方案
? ? 做服務無非就那幾步,啟動端口監聽、接收請求數據、分配資源受理,反饋應答數據,關閉釋放資源。一個優秀的服務端實現要考慮并發處理和對共享資源控制還是要費點心思的。Linux下提供了一個基于xinetd服務的低成本小制作解決方案,用起來超方便,優缺點放最后總結歡迎點評。
0001: /****************************************/ 0002: /* Author: gong_libin */ 0003: /* Date: 2000_01_01 */ 0004: /* File: GDeamon.c */ 0005: /****************************************/ 0006: 0007: /** 0008: * /etc/xinetd.d/GDeamon 0009: * service GDeamon 0010: * { 0011: * flags = REUSE 0012: * socket_type = stream 0013: * wait = no 0014: * user = root 0015: * server = /usr/bin/GDeamon 0016: * log_on_failure += USERID 0017: * disable = no 0018: * } 0019: * 0020: * /etc/services 0021: * GDeamon 321/tcp # The GDeamon Protocol 0022: */ 0023: 0024: #include <stdio.h> 0025: #include <stdlib.h> 0026: #include <string.h> 0027: #include <unistd.h> 0028: #include <fcntl.h> 0029: #include <time.h> 0030: 0031: #define G_STDIN stdin 0032: #define G_STDOUT stdout 0033: #define G_STDERR stderr 0034: 0035: #define G_TIMOUT 10 0036: #define G_PACKET 1024 0037: #define G_RESULT G_PACKET * G_PACKET 0038: 0039: int main(int argc, char* argv[]) 0040: { 0041: FILE* pstPipe = NULL; 0042: time_t ulTime = time(NULL); 0043: char szPacket[G_PACKET] = {0}; 0044: char szResult[G_RESULT] = {0}; 0045: int iCount = 0, iTotal = 0, iLength = 0; 0046: 0047: close(fileno(G_STDERR)); 0048: fcntl(fileno(G_STDIN), F_SETFL, O_NONBLOCK); 0049: 0050: if (fread(&iLength, sizeof(int), 1, G_STDIN) > 0) { 0051: while (iTotal < iLength) { 0052: if (time(NULL) - ulTime > G_TIMOUT) { 0053: printf("數據接收超時"); 0054: break; 0055: } 0056: if ((iCount = fread(&szPacket[iTotal], sizeof(char), G_PACKET - iTotal, G_STDIN)) > 0) { 0057: iTotal += iCount; 0058: } 0059: } 0060: if (iLength == strlen(szPacket)) { 0061: if (NULL != (pstPipe = popen(szPacket, "r"))) { 0062: if (NULL != fgets(szResult, G_PACKET, pstPipe)) { 0063: printf("%s", szResult); 0064: } 0065: pclose(pstPipe); 0066: } 0067: else { 0068: printf("命令執行失敗"); 0069: } 0070: } 0071: else { 0072: printf("數據長度錯誤"); 0073: } 0074: } 0075: 0076: return 0; 0077: }????009-018定義配置文件/etc/xinetd.d/Gdeamon,通知系統允許端口復用、傳輸層是TCP協議、不等待進程終止、進程歸屬root用戶、執行程序存放路徑等信息。
????021行追加到/etc/services文件中,通知系統傳輸層協議類型和監聽端口及服務名稱。
????047行關閉錯誤輸出免得添亂,48行設置標準輸入為非阻塞模式。
????050行從標準輸入讀取一個整形,在這個用例中這個整形用于表示后面數據的長度。
????051-059行根據上面整形值循環讀取數據直到讀取完畢或超時為止。
????060行判斷讀取數據的完整性。
????061-069把用戶發送過來的指令提交系統執行并通過管道獲取執行結果。
????063行把執行結果通過標準輸出返回。
????完事了就這么簡單省心省力滿足并發處理資源回收完全不操心,監聽端口監聽到連接的時候會fork子進程,同時把子連接的套接字傳下去,并把讀寫操作重定向到標準輸入輸出上,真欣賞這種簡單粗暴而又行之有效的做法。用例僅供參考,至于通信協議和異常機制沒做過多處理,需要自己加吧。
????優點:開發便利快捷,重點可放在業務流的上,處理并發量不大邏輯不復雜的接口半天時間連調帶測足夠;不僅支持tcp協議也支持udp協議,可以節省大量服務框架代碼的開發工作量;
????缺點:并發量一大力不從心,響應不夠快速高效,在線調測不夠方便;
????今晚有雨出門帶傘~
總結
- 上一篇: addEntriesFromDictio
- 下一篇: 【火炉炼AI】机器学习007-用随机森林