上午9点钟起来,吃了饭就在弄昨天找到的一个Http服务器,总共只有200行不到的代码,很快就看完了,也理解了,唯一要到网上查阅一下的就是HTTP协议,大致能看懂一点,但是我想多看看。
整了2个多小时,到近11点的时候就Ok了,把服务器弄好了,可以简单的浏览本地Html文件了,但是问题还有很多,比如子进程没有处理,让它们僵死了;还有这个程序只是用了一次读数据,内网倒不会有问题,外网的话,就不一定了,所以最好还是用循环的好。
还有一些问题就是看Unix网络编程了,Unix网络编程前面的内容就是围绕着一个简单的程序进行讲解socket的,各种各样的问题,技术。
这份代码以后我会重写,然后加入更多的元素,让它能够使用。服务器代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/stat.h>
#include<fcntl.h>
#define BACKLOG 3
#define BUFSIZE 10244
char not_found =
"HTTP/1.1 404 Not Found\r\n" "Content-Type: text/html\r\n"
"Content-Length: 40\r\n" "\r\n"
"<HTML><BODY>File not found</BODY></HTML>";
char bad_request =
"HTTP/1.1 400 Bad Request\r\n" "Content-Type: text/html\r\n"
"Content-Length: 39\r\n" "\r\n"
"<h1>Bad Request (Invalid Hostname)</h1>";
/char moved_permanently =
"HTTP/1.1 301 Moved Permanently\r\n" "Content-Length: 147\r\n" "Content-Type: text/html\r\n" "Location: %s\r\n" "\r\n" "<head><title>Document Moved</title></head><body><h1>Object Moved</h1>This document may be found <a HREF="\" mce_HREF="\""%s\">here</a></body>";
/
char head_analysis(char p);
void read_send(const char p, char pbuf, int connfd);
int main(void)
{
int listenfd;
struct sockaddr_in servAddr;
unsigned port = 80;
printf("HTTP Server is starting at port %d…\n", port);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == –1) {
printf("Invalid socket!\n");
return 1;
}
bzero(&servAddr, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(port);
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
printf("Server is listening…\n");
if (bind(listenfd, (struct sockaddr ) &servAddr,
sizeof(servAddr)) != 0) {
close(listenfd);
perror("Bind Error");
return 1;
}
printf("Binding server to port %d successfully.\n", port);
if (listen(listenfd, BACKLOG) != 0)
{
close(listenfd);
perror("Listen error");
return 1;
}
printf("Waiting client…\n");
while (1) {
struct sockaddr_in cliAddr;
size_t cliAddrLen = sizeof(cliAddr);
pid_t pid;
char p = NULL,
from[20],
file_name[100] = "/home/zqynux/network/",
rcvbuf[1024], sendbuf[BUFSIZE];
int connfd =
accept(listenfd, (struct sockaddr ) &cliAddr,
&cliAddrLen);
if (connfd < 0) {
close(listenfd);
printf("accept error\n");
return 1;
}
pid = fork();
if (pid == 0)
{
close(listenfd);
strcpy(from, inet_ntoa(cliAddr.sin_addr));
printf("\n\nclient %s CONNECTED.\n", from);
if (recv(connfd, rcvbuf, sizeof(rcvbuf), 0) > 0) {
printf("%s\n", rcvbuf);
p = head_analysis(rcvbuf);
} else {
perror("Read Error");
exit(0);
}
if (p != NULL) {
strcat(file_name, p);
printf("FILE NAME :%s\n", file_name);
read_send(file_name, sendbuf, connfd);
} else{
printf("No default html\n");
send(connfd, bad_request,
strlen(bad_request), 0);
}
close(connfd);
printf("DISCONNECTION TO CLIENT\n");
exit(0);
} else if (pid > 0)
close(connfd);
else
return 1;
}
close(listenfd);
return 0;
}
char head_analysis(char p)
{
char ptmp = p;
if (strncmp(ptmp, "GET /", 5) == 0) {
ptmp += 5;
while (ptmp != ‘ ‘)
ptmp++;
ptmp++ = ‘\0’;
if (strncmp(ptmp, "HTTP/", 5) == 0)
return p + 5;
else
return NULL;
}else
return NULL;
}
void read_send(const char p, char pbuf, int connfd)
{
int fd;
size_t rdLen;
fd = open(p, O_RDONLY);
if (fd != –1) {
send(connfd,
"HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n",
strlen
("HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n"),
0);
while ((rdLen = read(fd, pbuf, BUFSIZE)) > 0)
send(connfd, pbuf, rdLen, 0);
printf("WRITE TO CLIENT FINISHED\n");
close(fd);
} else{
send(connfd, not_found, strlen(not_found), 0);
printf("FILE Not Find\n");
}
}
至于客户端就是浏览器。