GVKun编程网logo

PHP中的HTTP服务器(php http服务器)

11

对于想了解PHP中的HTTP服务器的读者,本文将提供新的信息,我们将详细介绍phphttp服务器,并且为您提供关于C#实现一个最简单的HTTP服务器、C++实现简单的HTTP服务器、CentOS6.3

对于想了解PHP中的HTTP服务器的读者,本文将提供新的信息,我们将详细介绍php http服务器,并且为您提供关于C#实现一个最简单的HTTP服务器、C++实现简单的HTTP服务器、CentOS6.3搭建FTP服务器和HTTP服务器、FleaHttpd 小型快速的HTTP服务器的有价值信息。

本文目录一览:

PHP中的HTTP服务器(php http服务器)

PHP中的HTTP服务器(php http服务器)

我想为多个客户端在php中为服务器创建http套接字连接。我怎样才能做到这一点 ?我需要一些资源。

首先,我试图在java中创建服务器。我在java中创建服务器。并尝试从android应用程序访问。但是服务器找不到任何客户端。但是当我在java中创建客户端时,它正在工作。我该如何解决这个问题?

答案1

小编典典

看一下这篇文章:

Zend
用PHP编写套接字服务器

还可以尝试使用Google:

http://www.google.com/search?aq=0&oq=php+socket+server+mul&sourceid=chrome&ie=UTF-8&q=php+socket+server+multiple+clients

C#实现一个最简单的HTTP服务器

C#实现一个最简单的HTTP服务器

简介

  本文用C#实现了一个最简单的HTTP服务器类,你可以将它嵌入到自己的项目中,或者也可以阅读代码来学习关于HTTP协议的知识。

 背景

  高性能的WEB应用一般都架设在强大的WEB服务器上,例如IIS, Apache, 和Tomcat。然而,HTML是非常灵活的UI标记语言,也就是说任何应用和后端服务都可以提供HTML的生成支持。在这个小小的例子中,像IIS,、Apache这样的服务器消耗的资源太大了,我们需要自己实现一个简单的HTTP服务器,将它嵌入到我们的应用中用来处理WEB请求。我们仅需要一个类就可以实现了,很简单。

 代码实现

  首先我们来回顾一下如何使用类,然后我们再来分析实现的具体细节。这里我们创建了一个继承于HttpServer的类,并实现了handleGETRequest 和handlePOSTRequest  这两个抽象方法:

public class MyHttpServer : HttpServer {

 public MyHttpServer(intport):base(port)
 {

    }

    public override void handleGETRequest(HttpProcessor p) {

        Console.WriteLine("request: {0}", p.http_url);

        p.writeSuccess();

        p.outputStream.WriteLine("<html><body><h1>test server</h1>");

        p.outputStream.WriteLine("Current Time: " + DateTime.Now.ToString());

        p.outputStream.WriteLine("url : {0}", p.http_url);

 

        p.outputStream.WriteLine("<form method=post action=/form>");

        p.outputStream.WriteLine("<input type=text name=foo value=foovalue>");

        p.outputStream.WriteLine("<input type=submit name=bar value=barvalue>");

        p.outputStream.WriteLine("</form>");

    }

 

    public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData) {

        Console.WriteLine("POST request: {0}", p.http_url);

        stringdata = inputData.ReadToEnd();

        p.outputStream.WriteLine("<html><body><h1>test server</h1>");

        p.outputStream.WriteLine("<a href=/test>return</a><p>");

        p.outputStream.WriteLine("postbody: <pre>{0}</pre>", data);

    }

}

当开始处理一个简单的请求时,我们就需要单独启动一个线程来监听一个端口,比如8080端口:

HttpServer httpServer = new MyHttpServer(8080);

Thread  thread = new Thread(newThreadStart(httpServer.listen));

thread.Start();

如果你编译运行这个项目,你会在浏览器http://localhost:8080地址下看到页面上生成的示例内容。让我们来简单看一下这个HTTP服务器引擎是怎么实现的。

  这个WEB服务器由两个组件构成,一个是负责启动TcpListener来监听指定端口的HttpServer类,并且用AcceptTcpClient()方法循环处理TCP连接请求,这是处理TCP连接的第一步。然后请求到达“已指定“的端口,接着就会创建一对新的端口,用来初始化客户端到服务器端的TCP连接。这对端口便是TcpClient的session,这样就可以保持我们的主端口可以继续接收新的连接请求。从下面的代码中我们可以看到,每一次监听程序都会创建一个新的TcpClien,HttpServer类又会创建一个新的HttpProcessor,然后启动一个线程来操作。HttpServer类中还包含两个抽象方法,你必须实现这两个方法。

public abstract class HttpServer {

    protected int port;

    TcpListener listener;

    boolis_active = true;

    publicHttpServer(intport)
   {

        this.port = port;

    }

 

    public void listen() {

        listener = newTcpListener(port);

        listener.Start();

        while(is_active)
 {                

            TcpClient s = listener.AcceptTcpClient();

            HttpProcessor processor = newHttpProcessor(s,
this);

            Thread thread = newThread(newThreadStart(processor.process));

            thread.Start();

            Thread.Sleep(1);

        }

    }

 

    public abstract void handleGETRequest(HttpProcessor p);

    public abstract void handlePOSTRequest(HttpProcessor p, StreamReader inputData);

}

这样,一个新的tcp连接就在自己的线程中被HttpProcessor处理了,HttpProcessor的工作就是正确解析HTTP头,并且控制正确实现的抽象方法。下面我们来看看HTTP头的处理过程,HTTP请求的第一行代码如下:

GET /myurl HTTP/1.0

在设置完process()的输入和输出后,HttpProcessor就会调用parseRequest()方法。

public void parseRequest() {

    String request = inputStream.ReadLine();

    string[] tokens = request.Split('' '');

    if(tokens.Length != 3) {

        throw new Exception("invalid http request line");

    }

    http_method = tokens[0].ToUpper();

    http_url = tokens[1];

    http_protocol_versionstring = tokens[2];

 

    Console.WriteLine("starting: " + request);

}

HTTP请求由3部分组成,所以我们只需要用string.Split()方法将它们分割成3部分即可,接下来就是接收和解析来自客户端的HTTP头信息,头信息中的每一行数据是以Key-Value(键-值)形式保存,空行表示HTTP头信息结束标志,我们代码中用readHeaders方法来读取HTTP头信息:

public void readHeaders() {

    Console.WriteLine("readHeaders()");

    String line;

    while((line = inputStream.ReadLine()) != null)
 {

        if(line.Equals(""))
 {

            Console.WriteLine("got headers");

            return;

        }

 

        intseparator = line.IndexOf('':'');

        if(separator == -1) {

            throw new Exception("invalid http header line: " + line);

        }

        String name = line.Substring(0, separator);

        intpos = separator + 1;

        while((pos < line.Length) && (line[pos] == ''
 ''))
 {

            pos++;// 过滤掉所有空格

        }

 

        string value = line.Substring(pos, line.Length - pos);

        Console.WriteLine("header: {0}:{1}",name,value);

        httpHeaders[name] = value;

    }

}

到这里,我们已经了解了如何处理简单的GET和POST请求,它们分别被分配给正确的handler处理程序。在本例中,发送数据的时候有一个棘手的问题需要处理,那就是请求头信息中包含发送数据的长度信息content-length,当我们希望子类HttpServer中的handlePOSTRequest方法能够正确处理数据时,我们需要将数据长度content-length信息一起放入数据流中,否则发送端会因为等待永远不可能到达的数据和阻塞等待。我们用了一种看起来不那么优雅但非常有效的方法来处理这种情况,即将数据发送给POST处理方法前先把数据读入到MemoryStream中。这种做法不太理想,原因如下:如果发送的数据很大,甚至是上传一个文件,那么我们将这些数据缓存在内存就不那么合适甚至是不可能的。理想的方法是限制post的长度,比如我们可以将数据长度限制为10MB。

  这个简易版HTTP服务器另一个简化的地方就是content-type的返回值,在HTTP协议中,服务器总是会将数据的MIME-Type发送给客户端,告诉客户端自己需要接收什么类型的数据。在writeSuccess()方法中,我们看到,服务器总是发送text/html类型,如果你需要加入其他的类型,你可以扩展这个方法。

 

完整代码:

using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Bend.Util {

    public class HttpProcessor {
        public TcpClient socket;        
        public HttpServer srv;

        private Stream inputStream;
        public StreamWriter outputStream;

        public String http_method;
        public String http_url;
        public String http_protocol_versionstring;
        public Hashtable httpHeaders = new Hashtable();


        private static int MAX_POST_SIZE = 10 * 1024 * 1024; // 10MB

        public HttpProcessor(TcpClient s, HttpServer srv) {
            this.socket = s;
            this.srv = srv;                   
        }
        

        private string streamReadLine(Stream inputStream) {
            int next_char;
            string data = "";
            while (true) {
                next_char = inputStream.ReadByte();
                if (next_char == ''\n'') { break; }
                if (next_char == ''\r'') { continue; }
                if (next_char == -1) { Thread.Sleep(1); continue; };
                data += Convert.ToChar(next_char);
            }            
            return data;
        }
        public void process() {                        
            // we can''t use a StreamReader for input, because it buffers up extra data on us inside it''s
            // "processed" view of the world, and we want the data raw after the headers
            inputStream = new BufferedStream(socket.GetStream());

            // we probably shouldn''t be using a streamwriter for all output from handlers either
            outputStream = new StreamWriter(new BufferedStream(socket.GetStream()));
            try {
                parseRequest();
                readHeaders();
                if (http_method.Equals("GET")) {
                    handleGETRequest();
                } else if (http_method.Equals("POST")) {
                    handlePOSTRequest();
                }
            } catch (Exception e) {
                Console.WriteLine("Exception: " + e.ToString());
                writeFailure();
            }
            outputStream.Flush();
            // bs.Flush(); // flush any remaining output
            inputStream = null; outputStream = null; // bs = null;            
            socket.Close();             
        }

        public void parseRequest() {
            String request = streamReadLine(inputStream);
            string[] tokens = request.Split('' '');
            if (tokens.Length != 3) {
                throw new Exception("invalid http request line");
            }
            http_method = tokens[0].ToUpper();
            http_url = tokens[1];
            http_protocol_versionstring = tokens[2];

            Console.WriteLine("starting: " + request);
        }

        public void readHeaders() {
            Console.WriteLine("readHeaders()");
            String line;
            while ((line = streamReadLine(inputStream)) != null) {
                if (line.Equals("")) {
                    Console.WriteLine("got headers");
                    return;
                }
                
                int separator = line.IndexOf('':'');
                if (separator == -1) {
                    throw new Exception("invalid http header line: " + line);
                }
                String name = line.Substring(0, separator);
                int pos = separator + 1;
                while ((pos < line.Length) && (line[pos] == '' '')) {
                    pos++; // strip any spaces
                }
                    
                string value = line.Substring(pos, line.Length - pos);
                Console.WriteLine("header: {0}:{1}",name,value);
                httpHeaders[name] = value;
            }
        }

        public void handleGETRequest() {
            srv.handleGETRequest(this);
        }

        private const int BUF_SIZE = 4096;
        public void handlePOSTRequest() {
            // this post data processing just reads everything into a memory stream.
            // this is fine for smallish things, but for large stuff we should really
            // hand an input stream to the request processor. However, the input stream 
            // we hand him needs to let him see the "end of the stream" at this content 
            // length, because otherwise he won''t know when he''s seen it all! 

            Console.WriteLine("get post data start");
            int content_len = 0;
            MemoryStream ms = new MemoryStream();
            if (this.httpHeaders.ContainsKey("Content-Length")) {
                 content_len = Convert.ToInt32(this.httpHeaders["Content-Length"]);
                 if (content_len > MAX_POST_SIZE) {
                     throw new Exception(
                         String.Format("POST Content-Length({0}) too big for this simple server",
                           content_len));
                 }
                 byte[] buf = new byte[BUF_SIZE];              
                 int to_read = content_len;
                 while (to_read > 0) {  
                     Console.WriteLine("starting Read, to_read={0}",to_read);

                     int numread = this.inputStream.Read(buf, 0, Math.Min(BUF_SIZE, to_read));
                     Console.WriteLine("read finished, numread={0}", numread);
                     if (numread == 0) {
                         if (to_read == 0) {
                             break;
                         } else {
                             throw new Exception("client disconnected during post");
                         }
                     }
                     to_read -= numread;
                     ms.Write(buf, 0, numread);
                 }
                 ms.Seek(0, SeekOrigin.Begin);
            }
            Console.WriteLine("get post data end");
            srv.handlePOSTRequest(this, new StreamReader(ms));

        }

        public void writeSuccess() {
            outputStream.WriteLine("HTTP/1.0 200 OK");            
            outputStream.WriteLine("Content-Type: text/html;charset=utf-8");
            outputStream.WriteLine("Connection: close");
            outputStream.WriteLine("");
        }

        public void writeFailure() {
            outputStream.WriteLine("HTTP/1.0 404 File not found");
            outputStream.WriteLine("Connection: close");
            outputStream.WriteLine("");
        }
    }

    public abstract class HttpServer {

        protected int port;
        TcpListener listener;
        bool is_active = true;
       
        public HttpServer(int port) {
            this.port = port;
        }

        public void listen() {
            listener = new TcpListener(port);
            listener.Start();
            while (is_active) {                
                TcpClient s = listener.AcceptTcpClient();
                HttpProcessor processor = new HttpProcessor(s, this);
                Thread thread = new Thread(new ThreadStart(processor.process));
                thread.Start();
                Thread.Sleep(1);
            }
        }

        public abstract void handleGETRequest(HttpProcessor p);
        public abstract void handlePOSTRequest(HttpProcessor p, StreamReader inputData);
    }

    public class MyHttpServer : HttpServer {
        public MyHttpServer(int port)
            : base(port) {
        }
        public override void handleGETRequest(HttpProcessor p) {
            Console.WriteLine("request: {0}", p.http_url);
            p.writeSuccess();
            p.outputStream.WriteLine("<html><body><h1>test server</h1>");
            p.outputStream.WriteLine("Current Time: " + DateTime.Now.ToString());
            p.outputStream.WriteLine("url : {0}", p.http_url);

            p.outputStream.WriteLine("<form method=post action=/form>");
            p.outputStream.WriteLine("<input type=text name=foo value=foovalue>");
            p.outputStream.WriteLine("<input type=submit name=bar value=barvalue>");
            p.outputStream.WriteLine("</form>");
        }

        public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData) {
            Console.WriteLine("POST request: {0}", p.http_url);
            string data = inputData.ReadToEnd();

            p.outputStream.WriteLine("<html><body><h1>test server</h1>");
            p.outputStream.WriteLine("<a href=/test>return</a><p>");
            p.outputStream.WriteLine("postbody: <pre>{0}</pre>", data);
            

        }
    }

    public class TestMain {
        public static int Main(String[] args) {
            HttpServer httpServer;
            if (args.GetLength(0) > 0) {
                httpServer = new MyHttpServer(Convert.ToInt16(args[0]));
            } else {
                httpServer = new MyHttpServer(8080);
            }
            Thread thread = new Thread(new ThreadStart(httpServer.listen));
            thread.Start();
            return 0;
        }

    }

}

 

C++实现简单的HTTP服务器

C++实现简单的HTTP服务器

本文实例为大家分享了C++实现HTTP服务器的相关代码,供大家参考,具体内容如下

#include <Winsock2.h>
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
 
#pragma comment (lib,"ws2_32")
#define uPort 80
#define MAX_BUFFER   100000
#define SENDBLOCK   200000
#define SERVERNAME   "AcIDSoftWebServer/0.1b"
#define FileName   "HelloWorld.html"
 
typedef struct _NODE_ 
{
 SOCKET s;
 sockaddr_in Addr;
 _NODE_* pNext;
 
}Node,*pNode;
 
 
//多线程处理多个客户端的连接
typedef struct _THREAD_
{
 DWORD ThreadID;
 HANDLE hThread;
 _THREAD_* pNext;
}Thread,*pThread;
 
pNode pHead = NULL;
pNode pTail = NULL;
pThread pHeadThread = NULL;
pThread pTailThread = NULL;
 
bool InitSocket();//线程函数
DWORD WINAPI AcceptThread(LPVOID lpParam);
DWORD WINAPI ClientThread(LPVOID lpParam);
bool IoComplete(char* szRequest);     //数据包的校验函数
bool AddClientList(SOCKET s,sockaddr_in addr);
bool AddThreadList(HANDLE hThread,DWORD ThreadID);
bool ParseRequest(char* szRequest,char* szResponse,BOOL &bKeepAlive);
 
//我们存放Html文件的目录
char HtmlDir[512]={0};
 
void main()
{
 if (!InitSocket())
 {
  printf("InitSocket Error\n");
  return;
 }
 
 GetCurrentDirectory(512,HtmlDir);
 
 strcat(HtmlDir,"\\HTML\\");
 
 strcat(HtmlDir,FileName);
 //启动一个接受线程
 HANDLE hAcceptThread = CreateThread(NULL,AcceptThread,NULL,NULL);
 
 //在这里我们使用事件模型来实现我们的Web服务器
 //创建一个事件
 WaitForSingleObject(hAcceptThread,INFINITE);
}
 
DWORD WINAPI AcceptThread(LPVOID lpParam)   //接收线程
{
 //创建一个监听套接字
 SOCKET sListen = WSASocket(AF_INET,SOCK_STREAM,WSA_FLAG_OVERLAPPED); //使用事件重叠的套接字
 if (sListen==INVALID_SOCKET)
 {
  printf("Create Listen Error\n");
  return -1; 
 }
 //初始化本服务器的地址
 sockaddr_in LocalAddr;
 LocalAddr.sin_addr.S_un.S_addr = INADDR_ANY;
 LocalAddr.sin_family = AF_INET;
 LocalAddr.sin_port = htons(uPort);
 //绑定套接字 80端口
 int Ret = bind(sListen,(sockaddr*)&LocalAddr,sizeof(LocalAddr));
 if (Ret==SOCKET_ERROR)
 {
  printf("Bind Error\n");
  return -1;
 }
 //监听
 listen(sListen,5);
 //创建一个事件
 WSAEVENT Event = WSACreateEvent();
 if (Event==WSA_INVALID_EVENT)
 {
  printf("Create WSAEVENT Error\n");
  closesocket(sListen);
  CloseHandle(Event);     //创建事件失败 关闭套接字 关闭事件
  return -1;
 }
 //将我们的监听套接字与我们的事件进行关联属性为Accept
 WSAEventSelect(sListen,Event,FD_ACCEPT);
 WSANETWORKEVENTS NetWorkEvent;
 sockaddr_in ClientAddr;
 int nLen = sizeof(ClientAddr);
 DWORD dwIndex = 0;
 while (1)
 {
  dwIndex = WSAWaitForMultipleEvents(1,&Event,FALSE,WSA_INFINITE,FALSE);
  dwIndex = dwIndex - WAIT_OBJECT_0;
  if (dwIndex==WSA_WAIT_TIMEOUT||dwIndex==WSA_WAIT_Failed)
  {
   continue;
  }
  //如果有真正的事件我们就进行判断
  WSAEnumNetworkEvents(sListen,&NetWorkEvent);
  ResetEvent(&Event);   //
  if (NetWorkEvent.lNetworkEvents == FD_ACCEPT)
  {
   if (NetWorkEvent.iErrorCode[FD_ACCEPT_BIT]==0)
   {
    //我们要为新的连接进行接受并申请内存存入链表中
    SOCKET sClient = WSAAccept(sListen,(sockaddr*)&ClientAddr,&nLen,NULL);
    if (sClient==INVALID_SOCKET)
    {
     continue;
    }
    else
    {
     //如果接收成功我们要把用户的所有信息存放到链表中
     if (!AddClientList(sClient,ClientAddr))
     {
      continue;
     }  
    }
   }
  }
 }
 return 0;
}
 
DWORD WINAPI ClientThread(LPVOID lpParam)
{
 //我们将每个用户的信息以参数的形式传入到该线程
 pNode pTemp = (pNode)lpParam;
 SOCKET sClient = pTemp->s; //这是通信套接字
 WSAEVENT Event = WSACreateEvent(); //该事件是与通信套接字关联以判断事件的种类
 WSANETWORKEVENTS NetWorkEvent;
 char szRequest[1024]={0}; //请求报文
 char szResponse[1024]={0}; //响应报文
 BOOL bKeepAlive = FALSE; //是否持续连接
 if(Event == WSA_INVALID_EVENT)
 {
  return -1;
 }
 int Ret = WSAEventSelect(sClient,FD_READ | FD_WRITE | FD_CLOSE); //关联事件和套接字
 DWORD dwIndex = 0;
 while (1)
 {
  dwIndex = WSAWaitForMultipleEvents(1,FALSE);
  dwIndex = dwIndex - WAIT_OBJECT_0;
  if (dwIndex==WSA_WAIT_TIMEOUT||dwIndex==WSA_WAIT_Failed)
  {
   continue;
  }
  // 分析什么网络事件产生
  Ret = WSAEnumNetworkEvents(sClient,&NetWorkEvent);
  //其他情况
  if(!NetWorkEvent.lNetworkEvents)
  {
   continue;
  }
  if (NetWorkEvent.lNetworkEvents & FD_READ) //这里很有意思的
  {
    DWORD NumberOfBytesRecvd;
    WSABUF Buffers;
    DWORD dwBufferCount = 1;
    char szBuffer[MAX_BUFFER];
    DWORD Flags = 0;
    Buffers.buf = szBuffer;
    Buffers.len = MAX_BUFFER;
    Ret = WSARecv(sClient,&Buffers,dwBufferCount,&NumberOfBytesRecvd,&Flags,NULL);
    //我们在这里要检测是否得到的完整请求
    memcpy(szRequest,szBuffer,NumberOfBytesRecvd);
    if (!IoComplete(szRequest)) //校验数据包
    {
     continue;
    }
    if (!ParseRequest(szRequest,szResponse,bKeepAlive)) //分析数据包
    {
     //我在这里就进行了简单的处理
     continue;
    }
    DWORD NumberOfBytesSent = 0;
    DWORD dwBytesSent = 0;
    //发送响应到客户端
    do
    {
     Buffers.len = (strlen(szResponse) - dwBytesSent) >= SENDBLOCK ? SENDBLOCK : strlen(szResponse) - dwBytesSent; 
     Buffers.buf = (char*)((DWORD)szResponse + dwBytesSent);  
     Ret = WSASend(
      sClient,1,&NumberOfBytesSent,NULL);  
     if(SOCKET_ERROR != Ret)
      dwBytesSent += NumberOfBytesSent;
    }
    while((dwBytesSent < strlen(szResponse)) && SOCKET_ERROR != Ret); 
  }
 
  if(NetWorkEvent.lNetworkEvents & FD_CLOSE)
  {
    //在这里我没有处理,我们要将内存进行释放否则内存泄露
  }
 }
 return 0;
}
 
bool InitSocket()
{
 WSADATA wsadata;
 if (WSAStartup(MAKEWORD(2,2),&wsadata)==0)    //使用Socket前必须调用 参数 作用 返回值
 {
  return true;
 }
 return false;
}
 
bool AddClientList(SOCKET s,sockaddr_in addr)
{
 pNode pTemp = (pNode)malloc(sizeof(Node));
 HANDLE hThread = NULL;
 DWORD ThreadID = 0;
 if (pTemp==NULL)
 {
  printf("No Memory\n");
  return false;
 }
 else
 {
  pTemp->s = s;
  pTemp->Addr = addr;
  pTemp->pNext = NULL;
  if (pHead==NULL)
  {
   pHead = pTail = pTemp;
  }
  else
  {
   pTail->pNext = pTemp;
   pTail = pTail->pNext;
  }
  //我们要为用户开辟新的线程
  hThread = CreateThread(NULL,ClientThread,(LPVOID)pTemp,&ThreadID);
  if (hThread==NULL)
  {
   free(pTemp);
   return false;
  }
  if (!AddThreadList(hThread,ThreadID))
  {
   free(pTemp);
   return false;
  }
 }
 return true;
}
 
bool AddThreadList(HANDLE hThread,DWORD ThreadID)
{
 pThread pTemp = (pThread)malloc(sizeof(Thread)); 
 if (pTemp==NULL)
 {
  printf("No Memory\n"); 
  return false;
 }
 else
 {
  pTemp->hThread = hThread;
  pTemp->ThreadID = ThreadID;
  pTemp->pNext = NULL; 
  if (pHeadThread==NULL)
  {
   pHeadThread = pTailThread = pTemp;
  } 
  else
  {
   pTailThread->pNext = pTemp;  
   pTailThread = pTailThread->pNext;
  }
 }
 return true;
}
 
//校验数据包
bool IoComplete(char* szRequest)
{
 char* pTemp = NULL;   //定义临时空指针
 int nLen = strlen(szRequest); //请求数据包长度
 pTemp = szRequest;   
 pTemp = pTemp+nLen-4; //定位指针
 if (strcmp(pTemp,"\r\n\r\n")==0)   //校验请求头部行末尾的回车控制符和换行符以及空行
 {
  return true;
 }
 return false;
}
 
//分析数据包
bool ParseRequest(char* szRequest,BOOL &bKeepAlive)
{
 char* p = NULL;
 p = szRequest;
 int n = 0;
 char* pTemp = strstr(p," "); //判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。
 n = pTemp - p;    //指针长度
// pTemp = pTemp + n - 1; //将我们的指针下移
 //定义一个临时的缓冲区来存放我们
 char szMode[10]={0};
 char szFileName[10]={0};
 memcpy(szMode,p,n);   //将请求方法拷贝到szMode数组中
 if (strcmp(szMode,"GET")==0)  //一定要将Get写成大写
 { 
 //获取文件名
  pTemp = strstr(pTemp," ");
  pTemp = pTemp + 1;   //只有调试的时候才能发现这里的秘密
  memcpy(szFileName,pTemp,1);
  if (strcmp(szFileName,"/")==0)
  {
   strcpy(szFileName,FileName);
  }
  else
  {
   return false;
  }
 }
 else
 {
  return false;
 }
 // 分析链接类型
 pTemp = strstr(szRequest,"\nConnection: Keep-Alive");  //协议版本
 n = pTemp - p;
 if (p>0)
 {
  bKeepAlive = TRUE;
 }
 else  //这里的设置是为了Proxy程序的运行
 {
  bKeepAlive = TRUE;
 }
 //定义一个回显头
 char pResponseHeader[512]={0};
 char szStatusCode[20]={0};
 char szContentType[20]={0};
 strcpy(szStatusCode,"200 OK");
 strcpy(szContentType,"text/html");
 char szDT[128];
 struct tm *newtime;
 long ltime;
 time(<ime);
 newtime = gmtime(<ime);
 strftime(szDT,128,"%a,%d %b %Y %H:%M:%s GMT",newtime);
 //读取文件
 //定义一个文件流指针
 FILE* fp = fopen(HtmlDir,"rb");
 fpos_t lengthActual = 0;
 int length = 0;
 char* BufferTemp = NULL;
 if (fp!=NULL)
 {
  // 获得文件大小
  fseek(fp,SEEK_END);
  fgetpos(fp,&lengthActual);
  fseek(fp,SEEK_SET);
  //计算出文件的大小后我们进行分配内存
  BufferTemp = (char*)malloc(sizeof(char)*((int)lengthActual));
  length = fread(BufferTemp,(int)lengthActual,fp);
  fclose(fp);
  // 返回响应
  sprintf(pResponseHeader,"HTTP/1.0 %s\r\nDate: %s\r\nServer: %s\r\nAccept-Ranges: bytes\r\nContent-Length: %d\r\nConnection: %s\r\nContent-Type: %s\r\n\r\n",szStatusCode,szDT,SERVERNAME,length,bKeepAlive ? "Keep-Alive" : "close",szContentType);   //响应报文
 }
 //如果我们的文件没有找到我们将引导用户到另外的错误页面
 else
 {
 }
 strcpy(szResponse,pResponseHeader);
 strcat(szResponse,BufferTemp);
 free(BufferTemp);
 BufferTemp = NULL;
 return true;
}

以上就是本文的全部内容,希望对大家的学习有所帮助。

CentOS6.3搭建FTP服务器和HTTP服务器

CentOS6.3搭建FTP服务器和HTTP服务器

一、简介

FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。在FTP的使用当中,用户经常遇到两个概念:“下载”(Download)和“上传”(Upload)。“下载”文件就是从远程主机拷贝文件至自己的计算机上;“上传”文件就是将文件从自己的计算机中拷贝至远程主机上。用Internet语言来说,用户可通过客户机程序向(从)远程主机上传(下载)文件。

httpd是Apache超文本传输协议(HTTP)服务器的主程序。被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池。

本文使用vsftp作为FTP软件,使用lftp可以连接ftp。使用Apache的httpd作为http服务器。

二、FTP服务器

1、vsftp安装

检查vsftpd软件是否安装

#rpm -qa |grep vsftpd(显示vsftp版本则已安装)

安装vsftpd
#yum -y install vsftpd
启动
#service vsftpd start
开启启动
#chkconfig --level 345 vsftpd on

2、vsftp服务命令

启动ftp服务
#service vsftpd start
查看ftp服务状态
# service vsftpd status
重启ftp服务
# service vsftpd restart
关闭ftp服务

# service vsftpd stop

开启ftp服务前,需要关闭防火墙#service iptables stop

或将20和21端口加入防火墙:修改#vim/etc/sysconfig/iptables

3、vsftp配置

打开vsftpd主配置文件,配置完成后重启服务。

#vim /etc/vsftpd/vsftpd.conf

被禁止登陆FTP的用户文件

#vim /etc/vsftpd.ftpusers

允许登陆FTP的用户文件

#vim /etc/vsftpd.user_list

修改vsftpd.conf文件:

CentOS6.3搭建FTP服务器和HTTP服务器

也可以通过浏览器查看FTP服务器:

CentOS6.3搭建FTP服务器和HTTP服务器

三、HTTP服务器

(4)局域网若想访问:
配置防火墙,开启80端口

四、总结

(1)Linux构建服务器要比想象中简单的多,因为前人都已经做好了各种工作,要想有所突破必须有足够的积累。

(2)练习搭建更多的服务器,如FTP、HTTP、SVN、bugzilla等。

FleaHttpd 小型快速的HTTP服务器

FleaHttpd 小型快速的HTTP服务器

FleaHttpd 介绍

fleahttpd:“跳蚤服务器”,是一个用C从头写的一个轻量级网络伺服器,静态文件的抓取速度大概是Apache的三倍。

查看 FleaHttpd 与 Apache
之间的性能比较结果。

FleaHttpd 官网

http://code.google.com/p/fleahttpd/

关于PHP中的HTTP服务器php http服务器的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于C#实现一个最简单的HTTP服务器、C++实现简单的HTTP服务器、CentOS6.3搭建FTP服务器和HTTP服务器、FleaHttpd 小型快速的HTTP服务器等相关知识的信息别忘了在本站进行查找喔。

本文标签: