顺着教程1往下走,这个章节我们需要开发支持并发的web服务器,并加入容错处理

首先加入容错处理,建议将socket函数封装在新的wrap_socket.c文件中,并创建他的.h文件,Server端include该文件,重写Server端的部分代码。

wrap_socket.c文件应该是这样的:

#include "wrap_socket.h"

#define MAXLINE 1000

void p_error(char *str) {

printf("%s\n",str);

}

/*==========================*/

/* 这里是所有socket方法的封装*/

/*==========================*/

int Socket(int family,int type,int protocol) {

int socketfd = socket(family, type, protocol);

if(socketfd < 0) {

p_error("socket connect error\n");

return -1;

}

return socketfd;

}

void Bind(int fd, const struct sockaddr *sa, socklen_t len) {

if(bind(fd, sa, len) < 0 )

p_error("bind connect error\n");

}

void Listen(int fd,int backlog_size) {

if(listen(fd, backlog_size) < 0)

p_error("listen client error\n");

}

int Accept(int fd,const struct sockaddr *sa,socklen_t *len) {

int clientfd = accept(fd, sa, len);

if(clientfd < 0)

p_error("can't accept clientserver\n");

return clientfd;

}

void Connect(int fd,const struct sockaddr *sa,socklen_t len) {

if(connect(fd, sa, len) < 0)

p_error("connect to webserver error\n");

}

long Read(int fd, void *buf, size_t len) {

long n;

if((n = read(fd, buf, len)) == -1)

p_error("read error\n");

return n;

}

void Write(int fd, void *buf, size_t len) {

if(write(fd, buf, len) == -1 )

p_error("write error\n");

}

void Close(int fd) {

if(close(fd) == -1)

p_error("close fd error\n");

}

当然他对应的wrap_socket.h应该是这样的:

#ifndef wrap_socket_h

#define wrap_socket_h

#include

#include

#include

//read方法需要的头文件

#include

//socket方法需要的头文件

#include

#include

//htonl 方法需要的头文件

#include

//inet_ntop方法需要的头文件

#include

#include

#include

#include

#include

int Socket(int family,int type,int protocol);

int num_sum(int a,int b);

void Bind(int fd, const struct sockaddr *sa, socklen_t len);

void Listen(int fd,int backlog_size);

int Accept(int fd,const struct sockaddr *sa,socklen_t *len);

void Connect(int fd,const struct sockaddr *sa,socklen_t len);

long Read(int fd, void *buf, size_t len);

void Write(int fd, void *buf, size_t len);

void Close(int fd);

#endif /* wrap_socket_h */

这个时候 需要重写下webserver.c的部分socket文件了

listenfd = Socket(AF_INET, SOCK_STREAM, 0);

//初始化myaddr参数

bzero(&servaddr, sizeof(servaddr)); //结构体清零

//对servaddr 结构体进行赋值

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(SERV_PORT);

Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

Listen(listenfd, BACKLOGSIZE);

这个时候,跑下程序吧。调下bug,看看能不能顺利运行

接下来我们可以这样尝试,在开启一个Client 与Server交互的时候,再开启另一个Client连接Server,看能不能顺利运行,为什么?

这时候程序要能够支持并发的能力,就需要fork()这个方式,找个简单的例子说明下fork是这样的运行方式的

#include

#include

int main ()

{

pid_t fpid; //fpid表示fork函数返回的值

int count=0;

fpid=fork();

if (fpid < 0)

printf("error in fork!");

else if (fpid == 0) {

printf("i am the child process, my process id is %d/n",getpid());

printf("我是爹的儿子/n");//对某些人来说中文看着更直白。

count++;

}

else {

printf("i am the parent process, my process id is %d/n",getpid());

printf("我是孩子他爹/n");

count++;

}

printf("统计结果是: %d/n",count);

return 0;

}

当然我们这个程序也是要加上这个fork进行并发处理的,话不多说,献上代码

//死循环中进行accept()

while (1) {

cliaddr_len = sizeof(cliaddr);

//accept()函数返回一个connfd描述符

connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);

//fork()方法 创建一个跟父进程一摸一样的进程 pid <0 表示fork失败 pid==0表示为子进程 pid>0 为父进程 其pid=getpid();

pid = fork();

if(pid < 0) {

printf("fork error\n");exit(1);

}else if(pid == 0) {

while (1) {

n = Read(connfd, buf, MAXLINE);

if (n == 0) {

printf("the other side has been closed.\n");

break;

}

printf("received from %s at PORT %d,message is %s\n",

inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),

ntohs(cliaddr.sin_port),buf);

for (i = 0; i < n; i++)

buf[i] = toupper(buf[i]);

write(connfd, buf, n);

}

Close(connfd);

exit(0);

}else {

Close(connfd);

}

}

到此,大家试一试运行下,再开启新的client看看能不能顺利访问,我们还可以通过linux命令查看进程情况

ps -ef | grep webserver

初次启动是这样的

first_start_server.png

然后运行client,并多运行几次,就呃可以看到进程数在增加

second_start_server.png

好了,这个章节关于错误处理以及fork的内容到这了,第3章就开始真正进行web服务器的开发了原文章链接

linux下用c 开发web,用C一步步开发web服务器(2)相关推荐

  1. linux ftp 团队认证,linux下ftp和ftps以及ftp基于mysql虚拟用户认证服务器的搭建

    linux下ftp和ftps以及ftp基于mysql虚拟用户认证服务器的搭建 1.FTP协议:有命令和数据连接两种 命令连接,控制连接:21/tcp 数据连接: 主动模式,运行在20/tcp端口 和 ...

  2. linux定时备份数据库到远程ftp,Linux下自动备份MySQL数据库并上传到远程FTP服务器...

    Linux下自动备份MySQL数据库并上传到远程FTP服务器且删除指定日期前的备份Shell脚本 说明: 1.备份MySQL数据库存放目录/var/lib/mysql下面的xshelldata数据库到 ...

  3. linux下flex与bison源码安装,Win flex-bison开发环境配置

    Flex-Bison是一套很好很方便的工具,但是主要基于Linux,对于我这种喜(懒)欢(于)使(学)用(习) Windows(Linux)的主,希望能够在windows环境中使用这套工具.所幸,国外 ...

  4. linux下BLE(低功耗蓝牙协议)C语言开发笔记(2)---ble蓝牙扫描-连接-读写

    前言 bluez编译完后会生成很多命令行工具,比如gatttool.hcitool.bluetoothctl等,bluetoothctl的生成需要在configure的时候把--disable-tes ...

  5. 浅谈linux下websockets 的开发

    - 引言 WebSockets是HTML5支持的一种让浏览器与服务器全双工通信的协议,其以更小的开销高效的提供了Web连接.相较于经常推送实时数据到客户端甚至通过维护两个HTTP连接来模拟全双工连接的 ...

  6. linux通过进程看端口,linux下通过进程名查看其占用端口

    linux下通过进程名查看其占用端口: 1.先查看进程pid ps -ef | grep 进程名 2.通过pid查看占用端口 netstat -nap | grep 进程pid 例:通过nginx进程 ...

  7. linux首次登陆mysql设置密码,Linux下第一次使用MySQL数据库,设置密码

    在终端下输入:/etc/rc.d/init.d/mysqld status 查看MySQL状态,看看是否运行. 没有运行的话就输入:/etc/rc.d/init.d/mysqld start 这时,就 ...

  8. Linux下SENDMAIL+OPENWEBMAIL(2)

    我继续给大家讲LINUX下的SENDMAIL+OPENWEBMAIL 在LINUX下的SENDMAIL+OPENWEBMAIL(1)中所说的来初始OPENMAILSERVER服务器 看起来还是不行: ...

  9. LINUX下的APACHE的配置

    今天写一下LINUX下的APACHE的配置方法. APACHE是作为WEB服务器的.它的优点在于用缓存方式来加快网页的搜索速度. APACHE缺省只支持静态网页 LINUX下有APACHE的RPM包 ...

最新文章

  1. python3中unicode怎么写_详解python3中ascii与Unicode使用
  2. mongodb 索引去重_PostgreSQL13新特性解读Btree索引去重Deduplication
  3. oracle 游标循环 while,Oracle的游标使用方法 三种循环
  4. 动态规划简单应用:斐波那契数列
  5. web前端开发的好工具sublime
  6. jsoup爬虫教程技巧_Jsoup V的幕后秘密:优化的技巧和窍门
  7. 女生学师范还是计算机,本人专业是计算机科学与技术师范类,女生,不知道是考研还是工作什么的,今年开学大三,希望大家提点意见...
  8. python的深拷贝和浅拷贝
  9. OMS开发随笔之开发和部署要点
  10. edui 富文本编辑_ueditor集成秀米编辑器
  11. java和eova的关系_Eova 1.1 发布,Java Web 快速开发平台
  12. php exif信息,显示照片exif信息PHP代码
  13. MATLAB安装 C盘空间不足问题解决
  14. 领导合影站位图_领导座次安排示意图,各种场合都有,不懂很容易闹笑话!
  15. openstreetmap website部署
  16. TensorFlow使用GPU
  17. 引入第三方sdk错误提示
  18. 北师大计算机学院保研,北师大信息科学与技术学院保研-北京师范大学信息科学与技术学院保研推荐免试研究生方法...
  19. 大数据交易研究_学术著作 | 基于电商平台大数据的特征价格指数研究——统计研究...
  20. Beta分布(Beta Distribution)

热门文章

  1. Puppet Host资源介绍(二十一)
  2. 利用Swarmkit构建Windows/Linux混合Docker集群
  3. sphinx+coreseek创建中文分词索引
  4. 棋盘上的孙子兵法之我见
  5. 【jquery】一款不错的音频播放器——Amazing Audio Player
  6. linux系统下设置oracle开机自动启动
  7. 《软件测试实践--测试Web MSN》 之我的学习笔记(一)
  8. linux 魔兽 qq
  9. Hibernate实现对多个表进行关联查询
  10. Web UI设计的关键要素!