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.mzph.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;如果派生类中新增的成员函数与基类中的成员函数同…