会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><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>
// 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;}