首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > CGI >

会C,JavaScript的大侠,编写最简单的交互式Web服务器,

2012-03-07 
会C,JavaScript的大侠,编写最简单的交互式Web服务器,求助!现在在做Web server ,再看领导给我的C代码,公司

会C,JavaScript的大侠,编写最简单的交互式Web服务器,求助!
现在在做Web server ,再看领导给我的C代码,公司领导让我添加页面,我做到了,但是源代码里有很多函数,我搞不明白流程。

是个控制台的程序,我想自己实现一个最简单的Web Server,必须具备点击按钮后,送到服务器,服务器接受到后再送回来,显示在我的页面上。我已经写了个最简单的,但功能不能达到我的要求。

我的程序一运行,第一次可以在浏览器上看到一个页面,但是点击按钮后get发送出去,并没有被服务器正确处理。
recv被阻塞,等待一会后返回 -1,查看WSAGetLastError 说:远程软件关闭连接,看来是 ie 这边关闭了。

失败了。

WSAStartup //大致步骤如下
socket  
bind
listen
accept
while(1)
{
  recv
  send
}
closesocket
closesocket

HTML code
<html><head><title></title><script type="text/javascript" >function HTTPGet(){  var request=new ActiveXObject("MSXML2.XMLHTTP.3.0");  //...}</script><head><body><input type="textarea" id="textarea1"></textarea><input type="textarea" id="textarea2"></textarea><input type="button" id="button1" value="get" onclick="HTTPGet();" /></body></html>


get送出去后没反应。纠结,脑子里乱了。

各位大侠前辈们,谁能给个最简单的交互式Web服务器,带CGI的。

链接也可以,最好能麻烦您顺手写一个。

附上我的源代码,您可以在上面修改。

C/C++ code
// Web Server.cpp : 定义控制台应用程序的入口点。//#include <winsock2.h>    // 为了使用Winsock API函数#include <stdio.h>#include <string.h>#include <stdlib.h>#include <windows.h>// 告诉连接器与WS2_32库连接#pragma comment(lib,"WS2_32.lib")int readFile(char *fileSrc,char **pszText,DWORD *pfileSize){    FILE *fp=NULL;    char buf[1024+2]={0};    int size=0,len=0;    HANDLE hFile=NULL;    DWORD fileSize=0;    hFile=::CreateFile(fileSrc,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);    if(hFile == INVALID_HANDLE_VALUE)    {        printf("open file error.\n");        return -1;    }    fileSize=::GetFileSize(hFile,NULL);    *pfileSize=fileSize;    ::CloseHandle(hFile);    if(fileSize != 0)    {        *pszText=(char *)malloc(sizeof(char)*fileSize);    }    else        *pszText="";    fp=fopen(fileSrc,"rb");    if(fp == NULL)    {        printf("open file error.\n");        return -1;    }    do    {        size=fread(buf,sizeof(char),1024,fp);        if(size > 0)            len+=sprintf(*pszText+len,"%s",buf);        memset(buf,0,1024);    }while(size > 0);    fclose(fp);    return 0;}void getGMTTime(char *pSystemTime){    SYSTEMTIME st;    char wkday[16]={0},month[16]={0};    ::GetSystemTime(&st);    switch(st.wDayOfWeek)    {    case 0:strcpy(wkday,"Sun");break;    case 1:strcpy(wkday,"Mon");break;    case 2:strcpy(wkday,"Tue");break;    case 3:strcpy(wkday,"Wed");break;    case 4:strcpy(wkday,"Thu");break;    case 5:strcpy(wkday,"Fri");break;    case 6:strcpy(wkday,"Sat");break;    default:break;    }    switch(st.wMonth)    {    case 1:strcpy(month,"Jan");break;    case 2:strcpy(month,"Feb");break;    case 3:strcpy(month,"Mar");break;    case 4:strcpy(month,"Apr");break;    case 5:strcpy(month,"May");break;    case 6:strcpy(month,"Jun");break;    case 7:strcpy(month,"Jul");break;    case 8:strcpy(month,"Aug");break;    case 9:strcpy(month,"Sep");break;    case 10:strcpy(month,"Oct");break;    case 11:strcpy(month,"Nov");break;    case 12:strcpy(month,"Dec");break;    default:break;    }    sprintf(pSystemTime,"%3s, %02d %3s %04d %02d:%02d:%02d GMT",        wkday,        st.wDay,        month,        st.wYear,        st.wHour,        st.wMinute,        st.wSecond        );}int _tmain(int argc, _TCHAR* argv[]){    int size=0,len=0,packet_size=0;    DWORD fileSize=0;    char *szText=NULL;    char system_time[128]={0};    if(readFile("Myhtml.htm",&szText,&fileSize) == -1)        return -1;    // 初始化WS2_32.dll    WSADATA wsaData;    WORD sockVersion = MAKEWORD(2, 0);    ::WSAStartup(sockVersion, &wsaData);    // 创建套节字    SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    if(s == INVALID_SOCKET)    {        printf("Failed socket() \n");        ::WSACleanup();        return 0;    }    // 填充sockaddr_in结构    sockaddr_in sin;    sin.sin_family = AF_INET;    sin.sin_port = htons(8888);    //sin.sin_addr.S_un.S_addr = INADDR_ANY;    sin.sin_addr.S_un.S_addr=inet_addr("192.168.102.155");    // 绑定这个套节字到一个本地地址    if(::bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)    {        printf("Failed bind() \n");        ::WSACleanup();        return 0;    }    // 进入监听模式    if(::listen(s, 2) == SOCKET_ERROR)    {        printf("Failed listen()");        ::WSACleanup();        return 0;    }    printf("listen  ... \n");    // 循环接受客户的连接请求    sockaddr_in remoteAddr;     int nAddrLen = sizeof(remoteAddr);    SOCKET client;    char HTTPHead[512]={0};    char recvbuf[1024*4]={0};    while(TRUE)    {        // 接受一个新连接        client = ::accept(s, (SOCKADDR*)&remoteAddr, &nAddrLen);        if(client == INVALID_SOCKET)        {            printf("Failed accept()");            continue;        }        printf("accept 1 connect:    %s \r\n", inet_ntoa(remoteAddr.sin_addr));        while(1)        {            system("pause");            int recvSize=::recv(client,recvbuf,sizeof(recvbuf),0);            if(recvSize== SOCKET_ERROR)            {                printf("error=%d\n",::WSAGetLastError());                system("pause");            }            printf("%d\n",recvSize);            system("pause");            printf("%s\n",recvbuf);            getGMTTime(system_time);            sprintf(HTTPHead,"HTTP/1.1 200 OK\r\nDate: %s\r\nServer: WebServer\r\nContent-Length: %d\r\nContent-Type: text/html;charset=gb2312\r\nCache-Control: no-cache\r\nConnection: Keep-Alive\r\n\r\n",                system_time,                strlen(szText));            ::send(client,HTTPHead,strlen(HTTPHead),0);            printf("%s\n",HTTPHead);            // 向客户端发送数据            //::send(client, szText, strlen(szText), 0);            len=0;            size=0;            packet_size=1024;            do            {                if(fileSize - len > 1024)                    packet_size = 1024;                else if(fileSize - len <= 1024)                    packet_size = fileSize - len;                size=::send(client,szText+len,packet_size,0);                len+=size;            }while(size != SOCKET_ERROR && packet_size != 0);        }        printf("data send finished,closed.\n");        // 关闭同客户端的连接        ::closesocket(client);    }    // 关闭监听套节字    ::closesocket(s);    // 释放WS2_32库    ::WSACleanup();        free(szText);    return 0;} 



[解决办法]
这是HTTP服务器端吧?说几点看着不合理的地方

1,while(1)是什么意思?有一个客户端请求后,不停地循环接收客户端数据?而且没有用线程,当然阻塞了,这个程序会造成N个客户端请求的话,那么必须一个个的来。socket没有设置接收和发送超时的毫秒数,如果有客户端不自动关闭连接,那么recv会在60秒后超时,这时返回SOCKET_ERROR才能退出while(1),最后才能继续accept下一个客户端请求

建议:
A, accept后,另建线程,将socket传到线程里去完成while(1)包含的内容
B, 取消while(1)语句,recv一次即可,服务器端发送完数据后,关闭连接,退出线程
C, 设置socket接收和发送超时的毫秒数

2,system("pause");是debug用的么?服务器端还要按任意键才能继续操作?
建议:取消system("pause");有printf来调试已经够用了

热点排行