<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>waimv.com &#187; webservice</title>
	<atom:link href="http://www.waimv.com/tag/webservice/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.waimv.com</link>
	<description></description>
	<lastBuildDate>Fri, 09 Nov 2018 10:41:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>C语言实现的简单 Web 服务器</title>
		<link>http://www.waimv.com/linux/252/</link>
		<comments>http://www.waimv.com/linux/252/#comments</comments>
		<pubDate>Tue, 08 Jan 2013 06:45:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[webservice]]></category>

		<guid isPermaLink="false">http://www.szpian.com/?p=252</guid>
		<description><![CDATA[/* * WebServer.c * *  Created on: Nov 3, 2012 *      Author: pavithra * * A web server in C language using only the standard libraries. * The port number is passed as an argument. * */ #include &#60;stdio.h&#62; #include &#60;unistd.h&#62; #include &#60;stdlib.h&#62; #include &#60;string.h&#62; #include &#60;sys/types.h&#62; #include &#60;sys/socket.h&#62; #include &#60;netinet/in.h&#62; #include &#60;fcntl.h&#62; [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">/*</div>
<div id="_mcePaste">* WebServer.c</div>
<div id="_mcePaste">*</div>
<div id="_mcePaste">*  Created on: Nov 3, 2012</div>
<div id="_mcePaste">*      Author: pavithra</div>
<div id="_mcePaste">*</div>
<div id="_mcePaste">* A web server in C language using only the standard libraries.</div>
<div id="_mcePaste">* The port number is passed as an argument.</div>
<div id="_mcePaste">*</div>
<div id="_mcePaste">*/</div>
<div id="_mcePaste">#include &lt;stdio.h&gt;</div>
<div id="_mcePaste">#include &lt;unistd.h&gt;</div>
<div id="_mcePaste">#include &lt;stdlib.h&gt;</div>
<div id="_mcePaste">#include &lt;string.h&gt;</div>
<div id="_mcePaste">#include &lt;sys/types.h&gt;</div>
<div id="_mcePaste">#include &lt;sys/socket.h&gt;</div>
<div id="_mcePaste">#include &lt;netinet/in.h&gt;</div>
<div id="_mcePaste">#include &lt;fcntl.h&gt;</div>
<div id="_mcePaste">#include &lt;errno.h&gt;</div>
<div id="_mcePaste">#define EOL &#8220;\r\n&#8221;</div>
<div id="_mcePaste">#define EOL_SIZE 2</div>
<div id="_mcePaste">typedef struct {</div>
<div id="_mcePaste">char *ext;</div>
<div id="_mcePaste">char *mediatype;</div>
<div id="_mcePaste">} extn;</div>
<div id="_mcePaste">//Possible media types</div>
<div id="_mcePaste">extn extensions[] ={</div>
<div id="_mcePaste">{&#8220;gif&#8221;, &#8220;image/gif&#8221; },</div>
<div id="_mcePaste">{&#8220;txt&#8221;, &#8220;text/plain&#8221; },</div>
<div id="_mcePaste">{&#8220;jpg&#8221;, &#8220;image/jpg&#8221; },</div>
<div id="_mcePaste">{&#8220;jpeg&#8221;,&#8221;image/jpeg&#8221;},</div>
<div id="_mcePaste">{&#8220;png&#8221;, &#8220;image/png&#8221; },</div>
<div id="_mcePaste">{&#8220;ico&#8221;, &#8220;image/ico&#8221; },</div>
<div id="_mcePaste">{&#8220;zip&#8221;, &#8220;image/zip&#8221; },</div>
<div id="_mcePaste">{&#8220;gz&#8221;,  &#8221;image/gz&#8221;  },</div>
<div id="_mcePaste">{&#8220;tar&#8221;, &#8220;image/tar&#8221; },</div>
<div id="_mcePaste">{&#8220;htm&#8221;, &#8220;text/html&#8221; },</div>
<div id="_mcePaste">{&#8220;html&#8221;,&#8221;text/html&#8221; },</div>
<div id="_mcePaste">{&#8220;php&#8221;, &#8220;text/html&#8221; },</div>
<div id="_mcePaste">{&#8220;pdf&#8221;,&#8221;application/pdf&#8221;},</div>
<div id="_mcePaste">{&#8220;zip&#8221;,&#8221;application/octet-stream&#8221;},</div>
<div id="_mcePaste">{&#8220;rar&#8221;,&#8221;application/octet-stream&#8221;},</div>
<div id="_mcePaste">{0,0} };</div>
<div id="_mcePaste">/*</div>
<div id="_mcePaste">A helper function</div>
<div id="_mcePaste">*/</div>
<div id="_mcePaste">void error(const char *msg) {</div>
<div id="_mcePaste">perror(msg);</div>
<div id="_mcePaste">exit(1);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">/*</div>
<div id="_mcePaste">A helper function</div>
<div id="_mcePaste">*/</div>
<div id="_mcePaste">int get_file_size(int fd) {</div>
<div id="_mcePaste">struct stat stat_struct;</div>
<div id="_mcePaste">if (fstat(fd, &amp;stat_struct) == -1)</div>
<div id="_mcePaste">return (1);</div>
<div id="_mcePaste">return (int) stat_struct.st_size;</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">/*</div>
<div id="_mcePaste">A helper function</div>
<div id="_mcePaste">*/</div>
<div id="_mcePaste">void send_new(int fd, char *msg) {</div>
<div id="_mcePaste">int len = strlen(msg);</div>
<div id="_mcePaste">if (send(fd, msg, len, 0) == -1) {</div>
<div id="_mcePaste">printf(&#8220;Error in send\n&#8221;);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">/*</div>
<div id="_mcePaste">This function recieves the buffer</div>
<div id="_mcePaste">until an &#8220;End of line(EOL)&#8221; byte is recieved</div>
<div id="_mcePaste">*/</div>
<div id="_mcePaste">int recv_new(int fd, char *buffer) {</div>
<div id="_mcePaste">char *p = buffer; // Use of a pointer to the buffer rather than dealing with the buffer directly</div>
<div id="_mcePaste">int eol_matched = 0; // Use to check whether the recieved byte is matched with the buffer byte or not</div>
<div id="_mcePaste">while (recv(fd, p, 1, 0) != 0) // Start receiving 1 byte at a time</div>
<div id="_mcePaste">{</div>
<div id="_mcePaste">if (*p == EOL[eol_matched]) // if the byte matches with the first eol byte that is &#8216;\r&#8217;</div>
<div id="_mcePaste">{</div>
<div id="_mcePaste">++eol_matched;</div>
<div id="_mcePaste">if (eol_matched == EOL_SIZE) // if both the bytes matches with the EOL</div>
<div id="_mcePaste">{</div>
<div id="_mcePaste">*(p + 1 &#8211; EOL_SIZE) = &#8216;\0&#8242;; // End the string</div>
<div id="_mcePaste">return (strlen(buffer)); // Return the bytes recieved</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">} else {</div>
<div id="_mcePaste">eol_matched = 0;</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">p++; // Increment the pointer to receive next byte</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">return (0);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">/*</div>
<div id="_mcePaste">A helper function: Returns the</div>
<div id="_mcePaste">web root location.</div>
<div id="_mcePaste">*/</div>
<div id="_mcePaste">char* webroot() {</div>
<div id="_mcePaste">// open the file &#8220;conf&#8221; for reading</div>
<div id="_mcePaste">FILE *in = fopen(&#8220;conf&#8221;, &#8220;rt&#8221;);</div>
<div id="_mcePaste">// read the first line from the file</div>
<div id="_mcePaste">char buff[1000];</div>
<div id="_mcePaste">fgets(buff, 1000, in);</div>
<div id="_mcePaste">// close the stream</div>
<div id="_mcePaste">fclose(in);</div>
<div id="_mcePaste">char* nl_ptr = strrchr(buff, &#8216;\n&#8217;);</div>
<div id="_mcePaste">if (nl_ptr != NULL)</div>
<div id="_mcePaste">*nl_ptr = &#8216;\0&#8242;;</div>
<div id="_mcePaste">return strdup(buff);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">/*</div>
<div id="_mcePaste">Handles php requests</div>
<div id="_mcePaste">*/</div>
<div id="_mcePaste">void php_cgi(char* script_path, int fd) {</div>
<div id="_mcePaste">send_new(fd, &#8220;HTTP/1.1 200 OK\n Server: Web Server in C\n Connection: close\n&#8221;);</div>
<div id="_mcePaste">dup2(fd, STDOUT_FILENO);</div>
<div id="_mcePaste">char script[500];</div>
<div id="_mcePaste">strcpy(script, &#8220;SCRIPT_FILENAME=&#8221;);</div>
<div id="_mcePaste">strcat(script, script_path);</div>
<div id="_mcePaste">putenv(&#8220;GATEWAY_INTERFACE=CGI/1.1&#8243;);</div>
<div id="_mcePaste">putenv(script);</div>
<div id="_mcePaste">putenv(&#8220;QUERY_STRING=&#8221;);</div>
<div id="_mcePaste">putenv(&#8220;REQUEST_METHOD=GET&#8221;);</div>
<div id="_mcePaste">putenv(&#8220;REDIRECT_STATUS=true&#8221;);</div>
<div id="_mcePaste">putenv(&#8220;SERVER_PROTOCOL=HTTP/1.1&#8243;);</div>
<div id="_mcePaste">putenv(&#8220;REMOTE_HOST=127.0.0.1&#8243;);</div>
<div id="_mcePaste">execl(&#8220;/usr/bin/php-cgi&#8221;, &#8220;php-cgi&#8221;, NULL);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">/*</div>
<div id="_mcePaste">This function parses the HTTP requests,</div>
<div id="_mcePaste">arrange resource locations,</div>
<div id="_mcePaste">check for supported media types,</div>
<div id="_mcePaste">serves files in a web root,</div>
<div id="_mcePaste">sends the HTTP error codes.</div>
<div id="_mcePaste">*/</div>
<div id="_mcePaste">int connection(int fd) {</div>
<div id="_mcePaste">char request[500], resource[500], *ptr;</div>
<div id="_mcePaste">int fd1, length;</div>
<div id="_mcePaste">if (recv_new(fd, request) == 0) {</div>
<div id="_mcePaste">printf(&#8220;Recieve Failed\n&#8221;);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">printf(&#8220;%s\n&#8221;, request);</div>
<div id="_mcePaste">// Check for a valid browser request</div>
<div id="_mcePaste">ptr = strstr(request, &#8221; HTTP/&#8221;);</div>
<div id="_mcePaste">if (ptr == NULL) {</div>
<div id="_mcePaste">printf(&#8220;NOT HTTP !\n&#8221;);</div>
<div id="_mcePaste">} else {</div>
<div id="_mcePaste">*ptr = 0;</div>
<div id="_mcePaste">ptr = NULL;</div>
<div id="_mcePaste">if (strncmp(request, &#8220;GET &#8220;, 4) == 0) {</div>
<div id="_mcePaste">ptr = request + 4;</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">if (ptr == NULL) {</div>
<div id="_mcePaste">printf(&#8220;Unknown Request ! \n&#8221;);</div>
<div id="_mcePaste">} else {</div>
<div id="_mcePaste">if (ptr[strlen(ptr) - 1] == &#8216;/&#8217;) {</div>
<div id="_mcePaste">strcat(ptr, &#8220;index.html&#8221;);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">strcpy(resource, webroot());</div>
<div id="_mcePaste">strcat(resource, ptr);</div>
<div id="_mcePaste">char* s = strchr(ptr, &#8216;.&#8217;);</div>
<div id="_mcePaste">int i;</div>
<div id="_mcePaste">for (i = 0; extensions[i].ext != NULL; i++) {</div>
<div id="_mcePaste">if (strcmp(s + 1, extensions[i].ext) == 0) {</div>
<div id="_mcePaste">fd1 = open(resource, O_RDONLY, 0);</div>
<div id="_mcePaste">printf(&#8220;Opening \&#8221;%s\&#8221;\n&#8221;, resource);</div>
<div id="_mcePaste">if (fd1 == -1) {</div>
<div id="_mcePaste">printf(&#8220;404 File not found Error\n&#8221;);</div>
<div id="_mcePaste">send_new(fd, &#8220;HTTP/1.1 404 Not Found\r\n&#8221;);</div>
<div id="_mcePaste">send_new(fd, &#8220;Server : Web Server in C\r\n\r\n&#8221;);</div>
<div id="_mcePaste">send_new(fd, &#8220;&lt;html&gt;&lt;head&gt;&lt;title&gt;404 Not Found&lt;/head&gt;&lt;/title&gt;&#8221;);</div>
<div id="_mcePaste">send_new(fd, &#8220;&lt;body&gt;&lt;p&gt;404 Not Found: The requested resource could not be found!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&#8221;);</div>
<div id="_mcePaste">//Handling php requests</div>
<div id="_mcePaste">} else if (strcmp(extensions[i].ext, &#8220;php&#8221;) == 0) {</div>
<div id="_mcePaste">php_cgi(resource, fd);</div>
<div id="_mcePaste">sleep(1);</div>
<div id="_mcePaste">close(fd);</div>
<div id="_mcePaste">exit(1);</div>
<div id="_mcePaste">} else {</div>
<div id="_mcePaste">printf(&#8220;200 OK, Content-Type: %s\n\n&#8221;,</div>
<div id="_mcePaste">extensions[i].mediatype);</div>
<div id="_mcePaste">send_new(fd, &#8220;HTTP/1.1 200 OK\r\n&#8221;);</div>
<div id="_mcePaste">send_new(fd, &#8220;Server : Web Server in C\r\n\r\n&#8221;);</div>
<div id="_mcePaste">if (ptr == request + 4) // if it is a GET request</div>
<div id="_mcePaste">{</div>
<div id="_mcePaste">if ((length = get_file_size(fd1)) == -1)</div>
<div id="_mcePaste">printf(&#8220;Error in getting size !\n&#8221;);</div>
<div id="_mcePaste">size_t total_bytes_sent = 0;</div>
<div id="_mcePaste">ssize_t bytes_sent;</div>
<div id="_mcePaste">while (total_bytes_sent &lt; length) {</div>
<div id="_mcePaste">//Zero copy optimization</div>
<div id="_mcePaste">if ((bytes_sent = sendfile(fd, fd1, 0,</div>
<div id="_mcePaste">length &#8211; total_bytes_sent)) &lt;= 0) {</div>
<div id="_mcePaste">if (errno == EINTR || errno == EAGAIN) {</div>
<div id="_mcePaste">continue;</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">perror(&#8220;sendfile&#8221;);</div>
<div id="_mcePaste">return -1;</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">total_bytes_sent += bytes_sent;</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">break;</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">int size = sizeof(extensions) / sizeof(extensions[0]);</div>
<div id="_mcePaste">if (i == size &#8211; 2) {</div>
<div id="_mcePaste">printf(&#8220;415 Unsupported Media Type\n&#8221;);</div>
<div id="_mcePaste">send_new(fd, &#8220;HTTP/1.1 415 Unsupported Media Type\r\n&#8221;);</div>
<div id="_mcePaste">send_new(fd, &#8220;Server : Web Server in C\r\n\r\n&#8221;);</div>
<div id="_mcePaste">send_new(fd, &#8220;&lt;html&gt;&lt;head&gt;&lt;title&gt;415 Unsupported Media Type&lt;/head&gt;&lt;/title&gt;&#8221;);</div>
<div id="_mcePaste">send_new(fd, &#8220;&lt;body&gt;&lt;p&gt;415 Unsupported Media Type!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&#8221;);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">close(fd);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">shutdown(fd, SHUT_RDWR);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">int main(int argc, char *argv[]) {</div>
<div id="_mcePaste">int sockfd, newsockfd, portno, pid;</div>
<div id="_mcePaste">socklen_t clilen;</div>
<div id="_mcePaste">struct sockaddr_in serv_addr, cli_addr;</div>
<div id="_mcePaste">if (argc &lt; 2) {</div>
<div id="_mcePaste">fprintf(stderr, &#8220;ERROR, no port provided\n&#8221;);</div>
<div id="_mcePaste">exit(1);</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">sockfd = socket(AF_INET, SOCK_STREAM, 0);</div>
<div id="_mcePaste">if (sockfd &lt; 0)</div>
<div id="_mcePaste">error(&#8220;ERROR opening socket&#8221;);</div>
<div id="_mcePaste">bzero((char *) &amp;serv_addr, sizeof(serv_addr));</div>
<div id="_mcePaste">portno = atoi(argv[1]);</div>
<div id="_mcePaste">serv_addr.sin_family = AF_INET;</div>
<div id="_mcePaste">serv_addr.sin_addr.s_addr = INADDR_ANY;</div>
<div id="_mcePaste">serv_addr.sin_port = htons(portno);</div>
<div id="_mcePaste">if (bind(sockfd, (struct sockaddr *) &amp;serv_addr, sizeof(serv_addr)) &lt; 0)</div>
<div id="_mcePaste">error(&#8220;ERROR on binding&#8221;);</div>
<div id="_mcePaste">listen(sockfd, 5);</div>
<div id="_mcePaste">clilen = sizeof(cli_addr);</div>
<div id="_mcePaste">/*</div>
<div id="_mcePaste">Server runs forever, forking off a separate</div>
<div id="_mcePaste">process for each connection.</div>
<div id="_mcePaste">*/</div>
<div id="_mcePaste">while (1) {</div>
<div id="_mcePaste">newsockfd = accept(sockfd, (struct sockaddr *) &amp;cli_addr, &amp;clilen);</div>
<div id="_mcePaste">if (newsockfd &lt; 0)</div>
<div id="_mcePaste">error(&#8220;ERROR on accept&#8221;);</div>
<div id="_mcePaste">pid = fork();</div>
<div id="_mcePaste">if (pid &lt; 0)</div>
<div id="_mcePaste">error(&#8220;ERROR on fork&#8221;);</div>
<div id="_mcePaste">if (pid == 0) {</div>
<div id="_mcePaste">close(sockfd);</div>
<div id="_mcePaste">connection(newsockfd);</div>
<div id="_mcePaste">exit(0);</div>
<div id="_mcePaste">} else</div>
<div id="_mcePaste">close(newsockfd);</div>
<div id="_mcePaste">} /* end of while */</div>
<div id="_mcePaste">close(sockfd);</div>
<div id="_mcePaste">return 0; /* we never get here */</div>
<div id="_mcePaste">}</div>
]]></content:encoded>
			<wfw:commentRss>http://www.waimv.com/linux/252/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
