复制代码
然后还得准备一张JPG图片,作为资源文件,方便传递给浏览器,本地文件结构如下:
5. 案例代码: 搭建HTTP服务器
下面代码采用多线程形式响应浏览器的请求。
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
/*
函数功能: 服务器向客户端发送响应数据
*/
int HTTP_ServerSendFile(int client_fd,char *buff,char *type,char *file)
{
/1. 打开文件/
int fd=open(file,2);
if(fd<0)return -1;
/2. 获取文件大小/
struct stat s_buff;
fstat(fd,&s_buff);
/3. 构建响应头部/
sprintf(buff,“HTTP/1.1 200 OK\r\n”
“Content-type:%s\r\n”
“Content-Length:%d\r\n”
“\r\n”,type,s_buff.st_size);
/4. 发送响应头/
if(write(client_fd,buff,strlen(buff))!=strlen(buff))return -2;
/5. 发送消息正文/
int cnt;
while(1)
{
cnt=read(fd,buff,1024);
if(write(client_fd,buff,cnt)!=cnt)return -3;
if(cnt!=1024)break;
}
return 0;
}
/线程工作函数/
void *thread_work_func(void *argv)
{
int client_fd=(int)argv;
free(argv);
unsigned int cnt;
unsigned char buff[1024];
//读取浏览器发送过来的数据
cnt=read(client_fd,buff,1024);
buff[cnt]=‘\0’;
printf(“%s\n”,buff);
if(strstr(buff,“GET / HTTP/1.1”))
{
HTTP_ServerSendFile(client_fd,buff,“text/html”,“www/image_text.html”);
}
else if(strstr(buff,“GET /www/123.jpg HTTP/1.1”))
{
HTTP_ServerSendFile(client_fd,buff,“image/jpeg”,“www/888.jpg”);
}
else if(strstr(buff,“GET /favicon.ico HTTP/1.1”))
{
HTTP_ServerSendFile(client_fd,buff,“image/x-icon”,“www/1.ico”);
}
close(client_fd);
//退出线程
pthread_exit(NULL);
}
int main(int argc,char **argv)
{
if(argc!=2)
{
printf(“./app <端口号>\n”);
return 0;
}
signal(SIGPIPE,SIG_IGN); //忽略 SIGPIPE 信号–防止服务器异常退出
int sockfd;
/1. 创建socket套接字/
sockfd=socket(AF_INET,SOCK_STREAM,0);
int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
/2. 绑定端口号与IP地址/
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(atoi(argv[1])); // 端口号0~65535
addr.sin_addr.s_addr=INADDR_ANY; //inet_addr(“0.0.0.0”); //IP地址
if(bind(sockfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr))!=0)
{
printf(“服务器:端口号绑定失败.\n”);
}
/3. 设置监听的数量,表示服务器同一时间最大能够处理的连接数量/
listen(sockfd,20);
/4. 等待客户端连接/
int *client_fd;
struct sockaddr_in client_addr;
socklen_t addrlen;
pthread_t thread_id;
while(1)
{
addrlen=sizeof(struct sockaddr_in);
client_fd=malloc(sizeof(int));
*client_fd=accept(sockfd,(struct sockaddr *)&client_addr,&addrlen);
if(*client_fd<0)
{
printf(“客户端连接失败.\n”);
return 0;
}
printf(“连接的客户端IP地址:%s\n”,inet_ntoa(client_addr.sin_addr));
printf(“连接的客户端端口号:%d\n”,ntohs(client_addr.sin_port));
/创建线程/
if(pthread_create(&thread_id,NULL,thread_work_func,client_fd))
{
printf(“线程创建失败.\n”);
break;
}
/设置线程的分离属性/
pthread_detach(thread_id);
}
/5. 关闭连接/
为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!
这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。
本份面试集锦涵盖了
- 174 道运维工程师面试题
- 128道k8s面试题
- 108道shell脚本面试题
- 200道Linux面试题
- 51道docker面试题
- 35道Jenkis面试题
- 78道MongoDB面试题
- 17道ansible面试题
- 60道dubbo面试题
- 53道kafka面试
- 18道mysql面试题
- 40道nginx面试题
- 77道redis面试题
- 28道zookeeper
总计 1000+ 道面试题, 内容 又全含金量又高
- 174道运维工程师面试题
1、什么是运维?
2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?
3、现在给你三百台服务器,你怎么对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!