linux網絡編程(二)高并發服務器

linux網絡編程(二)高并發服務器

  • 錯誤處理
  • 高并發服務器
    • 多進程并發服務器
    • 客戶端

錯誤處理

#include "wrap.h"int Bind(int fd, const struct sockaddr* sa, socklen_t salen)
{int ret;if ((ret = bind(fd, sa, salen)) < 0){perror("bind error:");exit(1);}return ret;}int Accept(int fd, struct sockaddr* sa, socklen_t* salenptr)
{int ret;again:if ((ret = accept(fd, sa, salenptr)) < 0){if ((errno == ECONNABORTED) || (errno == EINTR)){goto again;}else{perror("accept error:");exit(1);}}return ret;}int Socket(int family, int type, int protocol)
{int ret;if ((ret=socket(family, type, protocol)) == -1){perror("socket error:");exit(1);}return ret;
}int Listen(int fd, int backlog)
{int ret;if ((ret = listen(fd, backlog)) < 0){perror("listen error:");exit(1);}return ret;}pid_t Fork()
{pid_t pid;pid = fork();if (pid < 0){perror("pid error:");exit(1);}else if (pid == 0){//子進程return pid;}else{//主進程return pid;}}ssize_t Read(int fd, void* ptr, size_t nbytes)
{ssize_t n;
again:if ((n = read(fd, ptr, nbytes)) == -1){if (errno == EINTR)goto again;elsereturn -1;}return n;
}

高并發服務器

在這里插入圖片描述

多進程并發服務器

使用多進程并發服務器時要考慮以下幾點:

  1. 父進程最大文件描述個數(父進程中需要close關閉accept返回的新文件描述符)
  2. 系統內創建進程個數(與內存大小相關)
  3. 進程創建過多是否降低整體服務性能(進程調度)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/wait.h>#include "wrap.h"
#define SERV_PORT 6666void* wait_child(int signo)
{while (waitpid(0, NULL, WNOHANG) > 0);return;
}int main()
{pid_t pid;int fsd,csd,n;char buf[BUFSIZ],clie_ip[BUFSIZ];struct sockaddr_in serv_addr,clie_addr;socklen_t clie_len;//創建套接字fsd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&serv_addr,sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(SERV_PORT);serv_addr.sin_addr.s_addr =htonl(INADDR_ANY) ;//綁定Bind(fsd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));Listen(fsd, 128);while(1){clie_len = sizeof(clie_addr);//接受客戶端 阻塞csd = Accept(fsd, (struct sockaddr*)&clie_addr, &clie_len);printf("client IP = %s , port =  %d \n",inet_ntop(AF_INET,&clie_addr.sin_addr.s_addr, clie_ip,sizeof(clie_ip)),ntohs(&clie_addr.sin_port));pid = Fork();if (pid == 0){//子進程close(fsd);break;}else{close(csd);//安裝信號,子進程結束回收signal(SIGCHLD,wait_child);}}//子進程 接受的客戶端的小寫字符轉化成大寫字符if (pid == 0){while (1){n = Read(csd, buf, sizeof(buf));if (n == 0){close(csd);return 0;}else if (n > 0){write(STDOUT_FILENO, buf, sizeof(buf));for (int i = 0; i < n; i++){//轉化大寫buf[i] = toupper(buf[i]);}write(csd, buf, n);}//清空數組memset(buf, 0, sizeof(buf));}}return 0;}

客戶端

#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <stdio.h>
#include <memory.h>#define CLIE_PORT 6666
#define CLIE_IP "118.178.192.222"int main()
{char buf[BUFSIZ] = {0};struct in_addr s; // IPv4地址結構體int cfd,ret,n;struct sockaddr_in addr;//客服端創建套接字cfd = socket(AF_INET,SOCK_STREAM,0);if (cfd == -1){perror("client error:");exit(1);}memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(CLIE_PORT);inet_pton(AF_INET, CLIE_IP,&addr.sin_addr.s_addr);ret =connect(cfd,(struct sockaddr *)&addr,sizeof(addr));if (ret <0){perror("connect error:");exit(1);}while (1){//從終端寫入fgets(buf,sizeof(buf),stdin);write(cfd,buf,strlen(buf));n=read(cfd, buf, sizeof(buf));printf("n = %d",n);if(n==0){exit(1);}write(STDOUT_FILENO, buf, n);memset(buf, 0, sizeof(buf));}close(cfd);return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384394.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384394.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384394.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux知識(一) 程序、進程與線程

linux知識&#xff08;一&#xff09; 程序、進程與線程程序進程程序如何變成進程&#xff1f;線程線程與進程fork和創建新線程的區別優點程序 程序&#xff1a;程序是已編譯好的二進制文件&#xff0c;存儲在磁盤中&#xff0c;不占用系統資源 程序包括&#xff1a; RO段&am…

linux 信號signal和sigaction理解

轉載&#xff1a;http://blog.csdn.net/beginning1126/article/details/8680757 今天看到unp時發現之前對signal到理解實在淺顯&#xff0c;今天拿來單獨學習討論下。 signal&#xff0c;此函數相對簡單一些&#xff0c;給定一個信號&#xff0c;給出信號處理函數則可&#xff…

linux知識(二)互斥量、信號量和生產者消費者模型

linux知識&#xff08;二&#xff09;互斥量、信號量和生產者消費者模型一、互斥量產生原因二、信號量生產者消費者模型一、互斥量 產生原因 使用多線程常常會碰到數據混亂的問題&#xff0c;那么使用互斥量&#xff0c;相當于“加鎖”的操作&#xff0c;將有助于解決數據混亂…

基于Linux的Socket編程之TCP全雙工Server-Client聊天程序

轉載&#xff1a;http://blog.csdn.net/apollon_krj/article/details/53437764#0-tsina-1-58570-397232819ff9a47a7b7e80a40613cfe1 一、引言&#xff1a; 由于accept函數、read、write、recv、send等函數都是是阻塞式的&#xff0c;在同一個進程之中&#xff0c;只要有任何一個…

數據結構(一)線性表

數據結構&#xff08;一&#xff09;線性表一、線性表定義二、順序表定義動態數組三、單鏈表定義不帶頭結點帶頭結點頭結點與不帶頭結點的區別頭插法與尾插法雙鏈表循環鏈表循環單鏈表循環雙鏈表靜態鏈表一、線性表定義 線性表是具有相同數據類型的n個數據元素的有限序列 特點…

linux網絡編程(二)TCP通訊狀態

linux網絡編程&#xff08;二&#xff09;TCP通訊狀態TCP狀態轉換為什么需要等待2MSL&#xff1f;端口復用TCP狀態轉換 tcp協議連接開始會經過三次握手&#xff0c;客戶端和服務器開始都會處于CLOSED狀態 第一次握手&#xff1a;客戶端會先發送SYN請求給服務器&#xff0c;客戶…

gethostbyname() 函數說明

轉載&#xff1a;http://www.cnblogs.com/cxz2009/archive/2010/11/19/1881611.html gethostbyname()函數說明——用域名或主機名獲取IP地址 包含頭文件 #include <netdb.h> #include <sys/socket.h> 函數原型 struct hostent *gethostbyna…

linux網絡編程(三)select、poll和epoll

linux網絡編程&#xff08;三&#xff09;select、poll和epoll一、為什么會有多路I/O轉接服務器&#xff1f;二、select三、poll三、epoll一、為什么會有多路I/O轉接服務器&#xff1f; 為什么會有多路I/O轉接服務器呢&#xff1f;在學這個之前&#xff0c;我們同使用的是多線…

Linux socket編程(一) 對套接字操作的封裝

轉載:http://www.cnblogs.com/-Lei/archive/2012/09/04/2670942.html 以前寫的&#xff0c;現在回顧一下&#xff1a; 下面是對socket操作的封裝&#xff0c;因為在Linux下寫中文到了windows里面會亂碼&#xff0c;所以注釋用英文來寫&#xff0c;有空再查下解決方法吧 socket.…

數據結構(二)棧

棧一、棧順序棧線性棧(不帶頭結點)線性棧(帶頭結點)共享棧一、棧 棧是只允許在一端進行插入或刪除操作的線性表。 棧頂&#xff1a;線性表允許進行插入刪除的那一端 棧底&#xff1a;固定的&#xff0c;不允許進行插入和刪除的那一端 空棧&#xff1a;不含如何元素的空表 順序…

如何在linux上安裝sqlite數據庫

如何在linux上安裝sqlite數據庫一、下載二、解壓三、配置&#xff08;configure&#xff09;四、編譯和安裝五、執行sqlite3程序六、測試代碼一、下載 首先要先下載sqlite3源碼包 鏈接&#xff1a;https://pan.baidu.com/s/1_70342ZLlPjLlqGzpy5IHw 提取碼&#xff1a;84ne …

數據結構(三)隊列

數據結構&#xff08;三&#xff09;隊列隊列隊列&#xff08;順序存儲&#xff09;循環隊列&#xff08;順序存儲&#xff09;隊列&#xff08;鏈式存儲&#xff09;隊列 隊列是一種受限制的線性表&#xff0c;只允許表的一端插入&#xff0c;在表的另一端刪除 隊列&#xf…

Linux fcntl函數詳解

轉載&#xff1a;http://www.cnblogs.com/xuyh/p/3273082.html 功能描述&#xff1a;根據文件描述詞來操作文件的特性。 文件控制函數 fcntl -- file control 頭文件&#xff1a; #include <unistd.h> #include <fcntl.h> 函數原型&#xff1a; …

vs2019使用sqlite數據庫遠程連接linux

vs2019使用sqlite數據庫遠程連接linux一、sqlite3添加到目錄二、添加依賴庫三、測試一、sqlite3添加到目錄 將兩個sqlite3頭文件放入目錄中 二、添加依賴庫 打開項目屬性 添加完成 三、測試 #include <stdio.h> #include <sqlite3.h>int main(int argc, cha…

linux網絡編程(四)線程池

linux網絡編程&#xff08;四&#xff09;線程池為什么會有線程池&#xff1f;實現簡單的線程池為什么會有線程池&#xff1f; 大多數的服務器可能都有這樣一種情況&#xff0c;就是會在單位時間內接收到大量客戶端請求&#xff0c;我們可以采取接受到客戶端請求創建一個線程的…

AIGC:大語言模型LLM的幻覺問題

引言 在使用ChatGPT或者其他大模型時&#xff0c;我們經常會遇到模型答非所問、知識錯誤、甚至自相矛盾的問題。 雖然大語言模型&#xff08;LLMs&#xff09;在各種下游任務中展示出了卓越的能力&#xff0c;在多個領域有廣泛應用&#xff0c;但存在著幻覺的問題&#xff1a…

關于C++子類父類成員函數的覆蓋和隱藏

轉載&#xff1a;http://blog.csdn.net/worldmakewayfordream/article/details/46827161 函數的覆蓋 覆蓋發生的條件&#xff1a; &#xff08;1&#xff09; 基類必須是虛函數&#xff08;使用virtual 關鍵字來進行聲明&#xff09; &#xff08;2&#xff09;發生覆蓋的兩個函…

數據結構(四)串的順序存儲

#include <stdio.h> #include <stdlib.h>#define MAXLEN 255 //定長順序存儲 typedef struct {char ch[MAXLEN]; //每個分量存儲一個字符int length; //串的實際長度 }SString;//串的初始化 bool StrAssign(SString& T, char* chars) {int i 0, len;char* …

數據結構(四)串的動態數組存儲

#include <stdio.h> #include <stdlib.h>#define MAXLEN 255 //定長順序存儲 typedef struct {char* ch; //每個分量存儲一個字符int length; //串的實際長度 }SString;//串的初始化 bool StrAssign(SString& T, char* chars) {int i 0, len;T.ch (char*)m…

C++名字隱藏

轉載&#xff1a;http://www.weixueyuan.net/view/6361.html 如果派生類中新增一個成員變量&#xff0c;該成員變量與基類中的成員變量同名&#xff0c;則新增的成員變量就會遮蔽從基類中繼承過來的成員變量。同理&#xff0c;如果派生類中新增的成員函數與基類中的成員函數同…