第35卷  第6期 福  建  电  脑 Vol. 35  No.6
2019年6月
Journal of Fujian Computer
Jun. 2019
———————————————
本文得到苏州市职业大学教学改革项目 (No.SZDJG-19007)资助。吴建平,男, 1966年生,博士,主要研究领域为计算机网络。E-mail:
jianping1016@hotmail 。陈珂,女,1974年生,硕士,主要研究领域为计算机应用技术、计算机视觉、大数据技术。E-mail: szchenke@163 。刘业,男,1977年生,博士,主要研究领域为人工智能。E-mail: liuye@jssvc.edu 。
C 语言编程的WWW 服务器的设计和实现
吴建平 陈珂 刘业
(苏州市职业大学计算机工程学院 江苏 苏州 215104)
摘  要 WWW 服务器的编程实现涉及到IP 、TCP 、HTTP 等计算机网络技术课程的重要协议和概念,也涉及到 C 语言编程中的多线程编程、套接字编程、简单的字符串分、关键词提取、句法分析等重要编程技巧。本文提出了通过C 语言编程实现WWW 服务器的整个思路和流程,并实现了WWW 服务器并附源码。本文对计算机网络技术开发和编程人员具有重要的参考价值和指导意义。
关键词 C 语言编程;网络编程技术;WWW 服务器实现 中图法分类号 TP393-4  DOI:10.16707/jki.fjpc.2019.06.027
Design and Implementation of WWW Server Using C Programming Language
WU Jianping, CHEN Ke, LIU Ye
(School of Computer Engineering, Suzhou Vocational University, Suzhou, China, 215104)
Abstract  The program implementation of WWW server involves IP, TCP, HTTP and other important protocols
and concepts in computer network course, and it also involves important programming techniques incl
uding multithread programming, socket programming, string parsing. We present a method and steps to realize WWW server using C language programming, and implement the server using Visual C++ and attach the source code. This paper is of important guidance to the computer network developers.
Keywords  C Programming Language; Network Programming Technique; WWW Server Implementation
1 引言
万维网(world wide web, WWW )服务器[1-2]是一种根据超文本传输协议(hypertext transfer protocol, HTTP )[3]对来自网络浏览器的请求进行响应和传输网页、图片、视频等资源的互联网设备。作为一种互联网的重要服务资源,它的正常运作不仅依赖于工作于应用层的HTTP ,还需要遵守互联网的两个最重要的协议,即工作于网络层的互联网协议(Internet protocol, IP)[4]和工作于传输层的传输控制协议(Transport control protocol, TCP)[5]。
通俗地说,IP 协议规定了互联网上每台连入网络的主机必须分配一个跟所在地理位置相关的号码,即IP 地址[6]。作为该主机在互联网上身份的唯
一标识,并规定了一系列完备的互联网通信机制。互联网实际的通信机制非常类似于快递运输,互联网
上数据是以数据分组(packet ,又称数据包,类似于快递包裹)为单位进行传输,其首部包含了数据源的IP 地址和目的地主机的IP 地址等重要信息,通过互联网路由交换机(其功能相当于快递中的物流中转站)通过存储转发的方式逐步传输至目的地。为缩短数据传输的延迟和提高传输的效率和灵活性,每个数据包的大小一般不超过2000字节,这样任何超过2000字节的文件在互联网上传输时
必须在发送端被切割成不大于2000字节的片段
(此过程相当于把完整的大型设备先拆解成方便运输的模块),这些片段在加上IP 首部信息发送至网络,由互联网路由器负责将其运送至目的地主机。每个
2019年福建电脑81
IP数据包均是独立传输的(类似于不同快递方式,如航空运输和地面运输之间时效差别,导致的后发先至现象),因此它们到达目的地的次序很可能跟发送的次序不同。在接收到所有IP数据包后,目的地主机把IP首部剥离后上传至传输层和应用层,它们会根据数据包的编号和长度信息对这些数据包进行重新装配,使之成为一个与发送文件完全一样的完整文件(此过程相当于把模块按序重新组装成原来的设备)。
一般情况下,一台主机上有多个应用程序会同时使用网络连接,有时候甚至一个应用程序(如服务器、
浏览器)会同时运行多个网络连接,这时候仅靠IP地址往往无法鉴别一个主机发送或接受的数据到底来源于或归属于哪个网络连接,TCP通过给同一主机上的每个有效网络连接设置一个由16位二进制数组成的端口号(TCP端口),提供了一种面向连接的、可靠的、基于数据流的传输通信协议。IP传输过程中发生的数据包丢失、数据包到达顺序错位、数据包校验错误等问题都由TCP协议予以完美解决。
与工作于网络层的IP和传输层的TCP不同,HTTP协议工作于应用层,主要用于在WWW服务器(server)和浏览器(browser)之间进行面向连接的互动交流和超文本文件传输。目前主要包括两种版本,即HTTP/1.0和HTTP/1.1。这里的超文本文件对象包括图像、视频、音频等各种格式,HTTP 传输的数据可以被压缩以提高传输效率,但数据在传输过程中并不会被加密,因此容易被窃取。为避免敏感的机密数据泄露,HTTP又颁布了更安全的扩展版本HTTPS(Hypertext Transfer Protocol Secure, 超文本安全传输协议)[7-8]。
HTTP协议的主要优点在于其语法结果的简单性。浏览器向服务器发送的请求类型主要包括GET 和POST,其中GET用于从服务器端请求文件,而POST则用于向服务器发送html页面输入的数据和向服务器上传文件等。为进一步简化服务器和浏览器之间的互动方式,HTTP还规定了服务器在每次接受浏览器连接后仅处理一个请求,在完成请求任务并收到客户的应答后即切断连接,确保了服务器工作机制的简洁性、可靠性和稳定性。原则上,HTTP允许传输任意类型的文件和数据对象,通过服务器发送响应数据中的Content-Type进行标记,这一特点确保了HTTP在传输数据时的包容性。最后,HTTP协议作为
一种无状态协议,对于事务处理没有记忆能力(服务器无法判断客户端的请求是否重复),这种简单的事务处理机制虽然在某些特殊情况下会影响服务器的正常工作(如某些来自客户端的恶意攻击导致服务器忙于应付,从而无暇对来自其他客户端的正常请求予以响应),但最大限度地保障了服务器的应答速度。
2WWW服务器的设计
创建套接字S
初始化网络参数
为套接字S绑定IP地
址和TCP端口地址
对套接字S进行侦听,
设定同一时间允许客户
连接数目的上限
有来自客户端
浏览器的连接
请求
创建新线程T
关闭套接字S
关闭套接字S,关
闭当前服务器
分析套接字C上接
收到的数据包
向客户浏览器发送
文件
创建新套接字C
关闭套接字C
结束线程T
图1 WWW服务器的设计思路
WWW服务器包括前台和后台两个部分,其中前台部分主要用于显示和监控当前连接服务器的客户端信息。而后台部分则承担了所有的服务器功能,如图1所示,包括服务器套接字创建、套接字与IP地址和TCP端口号的绑定、服务器对客户端连接请求的侦听、对客户端连接请求的接受并创建新的专门用于服务器完成客户端请求任务的套接字,最后是服务器通过新创建套接字与客户端之间的互动(包括接收客
户端发送的请求信息,对信息的句法分析和合理响应,在完成请求任务后关闭与客户端的连接等)。本文通过C和Visual C++语言来实现服务器。
3WWW服务器的实现
3.1服务器的创建、绑定和侦听
服务器启动和运行所涉及的函数,主要包括
82 吴建平等:C语言编程的WWW服务器的设计和实现第6期
socket ()[9](创建套接字),bind ()(把socket()函数创建的套接字绑定在本地的某个TCP端口上),listen () (侦听客户端请求,并设定允许对服务器进行同时访问的最大客户端连接数),accept() (对客户端浏览器连接请求表示同意,并创建新的套接字用于响应浏览器的HTTP请求),此后利用线程创建函数AfxBeginThread()[10]为每一个新创建的套接字创建一个新的线程。在新线程中通过recv () 函数接收浏览器发送的HTTP请求数据包,对接收到的数据包进行分析后,根据请求内容利用函数send ()向浏览器发送HTTP首部和相应文件。其中文件切割成长度不超过2000字节的数据分组利用send()函数分多次发送。服务器完成一个客户端的请求后,首先调用shutdown()函数通知浏览器数据发送完毕,再调用Closesocket ()函数彻底关闭服务器与客户端的连接,然后结束线程。
下列列出了套接字从创建到侦听的部分重要Visual C++语言源码。详细的源码请见链接:pan.baidu/s/1RzaQIugPrz1TmnRyoX4AN w,提取码为7qcd。
//初始化网络参数
WSADATA wsaData;
if (::WSAStartup(0x202, &wsaData) != 0){
AfxMessageBox(_T("未能成功初始化网络套接字!"));
return;
}
/* 新建一个socket,用户侦听客户端连接请求*/ if ((listen_socket=socket(AF_INET,
SOCK_STREAM, 0)) == INVALID_SOCKET){ AfxMessageBox("未能成功创建侦听套接字,退出程序");
exit(1);
}
/*设置本地IP地址和TCP端口地址*/
struct sockaddr_in serv_addr;
memset((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(m_port);c编程网站
/*把带有本地IP地址和TCP端口信息的数据块与套接字绑定*/
if (bind(listen_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
AfxMessageBox("无法邦定到TCP端口");
return;
}
/*对邦定的服务器socket 通道进行侦听,等待客户端的连接请求。设置最多可以同时容许10个客户机进行连接*/
listen(listen_socket, 10);
/*利用while无限循环来不断接受客户端连接请求*/ while (server_state){
//接收客户端的请求并创建新的套接字newsockfd用于与客户端沟通
if ((newsockfd = accept(listen_socket, (struct sockaddr *) &client_addr, &clilen)) == 0)
continue;
else if (newsockfd < 0)
exit(0);
//启动新线程负责与客户端进行通讯(包括向客户端发送和从客户端接收信息)AfxBeginThread(processHTTPRequest, (LPVOID *)&newsocket);
}
3.2 服务器与浏览器的互动
图2 服务器接收到的来自浏览器的请求内容
客户端浏览器在和服务器连接成功后,随即向服务器发送一个数据分组,用于告知服务器浏览器的请求内容,其格式如图2所示。请求数据包的第一行为请求行,规定了请求类型(GET),要访问的资源(/img0010.jpg),以及使用的HTTP版本(HTTP1.1),后面的数行为附加行,对于服务器而言并不重要。服务器只对该数据包的第一行进行分析。然后,服务器会向浏览器首先发送响应信息的首部。首部一般至少包括下列四行信息:
HTTP/1.1 200 OK
Date: Fri, 26 April 2019 10:07:21 GMT
Content-Type: image/jpg
Content-length:103948
Connection: close
2019年福建电脑83
其中第一行极为重要,包括HTTP版本号、状
态码(浏览器请求是否有语法错误、是否合法、资
源是否存在等),这里的200表示客户请求成功;
第二行是响应的时间戳;第三行规定了请求内容的
类型(这里请求的资源为图像,以jpg格式存储);
第四行通知浏览器资源文件的大小(这里为103948
字节,是服务器向浏览器实际发送的字节数);第
五行通知客户端浏览器服务器将在发送完资源文
件后关闭连接。
随后,服务器把资源数据(长度103948字节)
分割成数据包(大小不超过2000字节)后发送给
浏览器端(52个数据分组)。在发送完毕后,服务
器调用shutdown()函数关闭本次连接,然后调用
closesocket()函数释放当前套接字资源。
4 WWW服务器演示
图3为本人专门为本服务器开发的界面。点击启动服务器后,服务器开始工作,网址在界面上显示,浏览器可以直接通过输入服务器的主机名SKY-20190311EFP以及TCP端口地址8888来访问(在浏览器地址栏中输入:sky- 20190311 EFP:8888)。另外也可直接输入服务器的IP地址加TCP端口号:192.168.42.189:8888来访问服务器主页。
图3 服务器界面
图4为通过QQ浏览器访问上述服务器后返回的网页,由于网页中包含一段视频和三个图像文件。浏览器
实际向服务器发送了5个资源请求,其中第一个请求为访问主页;在浏览器分析主页中包含的1个视频和3个图像文件后又分别向服务器发送4个请求。这些请求在图3的服务器界面中均有记录。
图4 浏览器访问服务器主页界面
5结束语
本文提出并实现了一种简单的基于Visual C++编程的WWW服务器的方法。本文所述方法对从事网络编程和开发的人员有较好的指导意义。
参考文献
[1] 孙涛. RHEL 下开源www 服务器的部署. 网络与通信技术,
2015(14):100-101
[2] 王海燕.在校园网中利用Linux 构建WWW 服务器.电脑知识与技
术, 2008,3(8):1671-1672
[3] 孙霞. 基于java的高效多线程HTTP服务器的研究及实现.福建电脑,
2003,19(11):38-39
[4] 王绍强,邵丹,李晓辉.网络工程专业TCP/IP协议课程设计.计算机教
育,2013,10(14):42-45
[5] 刘晓天.基于TCP协议的网络应用设计与开发.山东农业工程学院学
报,2017, 17(8):163-164
[6] 李卓.IPv4向IPv6的过渡技术研究.资有线电视技术,2019,
36(3):63-64
[7] 张宝玉.浅析HTTPS协议的原理及应用.网络安全技术与应用,
2016,14(7):36-37
[8] 潘思聪.一种高性能可靠服务器的设计与实现.桂林航天工业学院学
报, 2018(01):12-17
[9] 王香菊.VC++使用Winsock API实现网络通讯的方法.通讯世界,
2016(13):100-101
[10] 钟垣如.VC++编程技术与技巧研究.计算机与网络
, 2015(11):71-72

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。