Перед тем как мы будет учиться отвечать клиенту не просто HTML страницей, а послав перед этим заголовок я решил внести изменения в организацию кода. Просто чтобы читалось легче.
В предыдущем примере мы просто пытались читать данные и записывать их в LOG, но вообще-то прочитать данные можно не всегда. Мы использовали функцию recv, которая возвращает значение.
Если ошибок нет, то функция вернет количество прочитанных байт. Если прочитаны все данные, то ноль, в случае ошибки вернется SOCKET_ERROR. Вот это мы и предусмотрим сейчас.
int ErrorRecv; char bufferrecv[200]; ErrorRecv=recv(HTTPServer.clientsocket,bufferrecv,sizeof(bufferrecv),0); if (ErrorRecv !=SOCKET_ERROR ) { if (ErrorRecv==0) { HTTPServer.LogsWriteNotTime("Прочитанные данные:"); HTTPServer.LogsWriteNotTime(bufferrecv); } }
Чтение данных подразумевает и их анализ. Ведь нам нужно же знать запрос какого файла производится. Поэтому я решил чтение данных вынести в отдельную процедуру.
afx_msg LRESULT CHTTPServerView::OnServerAccept(WPARAM wParam, LPARAM lParam) { //....... HTTPServer.LogsWriteNotTime("Адрес клинета - " + addr); HTTPServer.ReadDataClient(); CString buff="<html>\n<p>Сайт шаг за шагом представляет\n</html>\r\n"; //....... } BOOL CSeverWinSock::ReadDataClient() { int ErrorRecv; char bufferrecv[200]; ErrorRecv=recv(clientsocket,bufferrecv,sizeof(bufferrecv),0); if (ErrorRecv !=SOCKET_ERROR ) { if (ErrorRecv>0) { LogsWriteNotTime("Прочитанные данные:"); LogsWriteNotTime(bufferrecv); return TRUE; } } return FALSE; }
И еще мне не очень нравится, что для изменения возврата мне приходится перекомпилирировать код. HTML страница должна быть на диске :-))
afx_msg LRESULT CHTTPServerView::OnServerAccept(WPARAM wParam, LPARAM lParam) { //...... HTTPServer.ReadDataClient(); HTTPServer.SendFile("c:\\host\\default.htm"); closesocket(HTTPServer.clientsocket); //...... } BOOL CSeverWinSock::SendFile(CString FileName) { CFile cf(FileName,CFile::modeRead); DWORD fileLeght=cf.GetLength(); char *p; p=new char[fileLeght]; cf.Read(p,fileLeght); SendData(p,fileLeght); return TRUE; } void CSeverWinSock::SendData(LPSTR buff,DWORD size) { int Errors; Errors = send(clientsocket,(LPSTR)buff,size,0); if (Errors == SOCKET_ERROR) AfxMessageBox("Error Send"); }