大家好,c小白一個,練習寫http服務器端,代碼如下:
問題;
以下代碼編譯好后在cmd視窗中運行后,
1. 在瀏覽器中輸入http://localhost:8088/test9.html , test9.html檔案是不存在的,
本意是要在瀏覽器輸出錯誤資訊:“發生錯誤!查看請求檔案名和請求方式!”,但瀏覽器是一片空白, 但在cmd除錯輸出,是有http協義
議輸出了字串呀,如以下圖1所示, 請問是哪行代碼出了問題
2. 在瀏覽器中輸入http://localhost:8088/test.html , test.html檔案是存在的, 但檔案的內容沒有輸出完整
如下圖2所示,請問問題出在哪里,
// tcps.cpp : 定義控制臺應用程式的入口點。
// 服務器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stdafx.h"
#include <WinSock2.h>
#include <process.h>
#pragma comment(lib,"WS2_32.lib")
#define BUF_SIZE 2048
#define BUF_SMALL 100
#define PORT 8888
unsigned WINAPI RequestHandler(void* arg);
char* ContentType(char* file);
void SendData(SOCKET sock, char* ct, char* fileName);
void SendErrorMSG(SOCKET sock);
void ErrorHandling(char* message);
char recvData[BUF_SIZE];
int nclients = 0;
int main(int argc, char* argv[])
{
//初始化元件ws2_32.dll ,協商版本
WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
SOCKET hServSock, hClntSock;
SOCKADDR_IN servAdr, clntAdr;
HANDLE hThread;
DWORD dwThreadID;
int clntAdrSize;
if (argc!=2)
{
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
if (WSAStartup(sockVersion, &wsaData) != 0)
{
ErrorHandling("WSAStartup() error!");
}
//創建socket套接字,指定使用TCP協議
hServSock = socket(PF_INET, SOCK_STREAM, 0);
if (hServSock == INVALID_SOCKET)
{
//printf("創建socket失敗!\n");
//return 0;
ErrorHandling("創建socket失敗!");
}
//填充服務器相關地址資訊,系結IP地址,協議及埠
//struct sockaddr_in server;
memset(&servAdr, 0, sizeof(servAdr));
servAdr.sin_family = AF_INET;
servAdr.sin_addr.s_addr=htonl(INADDR_ANY);
servAdr.sin_port = htons(atoi(argv[1]));
if (bind(hServSock, (LPSOCKADDR)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
ErrorHandling("系結地址失敗!");
//開始監聽
if (listen(hServSock, 5) == SOCKET_ERROR)
ErrorHandling("listen() error");
printf("服務器已啟動");
//回圈接收資料
//SOCKET clientsocket;
//struct sockaddr_in clientaddr;
//int nclientaddrlen = sizeof(clientaddr);
while (1)
{
//printf("\n等待連接......\n");
clntAdrSize = sizeof(clntAdr);
hClntSock = accept(hServSock, (SOCKADDR*)&clntAdr, &clntAdrSize);
if (hClntSock == INVALID_SOCKET)
{
printf("接受客戶端連接錯誤!");
continue;
}
// 注意如果寫成http服務器以下這一句是不能要的,否則瀏覽器端是不會有任何顯示的,輸出也沒有遵行http協議
// 再一個要開啟多執行緒模式才行,否則也會造成瀏覽器客戶端的通訊堵塞
//printf("客戶端%s連接成功!\n",inet_ntoa(clientaddr.sin_addr));
printf("\n connection Request:%s:%d\n",inet_ntoa(clntAdr.sin_addr),ntohs(clntAdr.sin_port));
hThread = (HANDLE)_beginthreadex(NULL, 0, RequestHandler, (void*)hClntSock, 0, (unsigned*)&dwThreadID);
}
//關閉服務器套接字,清理并釋放相關資源
closesocket(hServSock);
WSACleanup();
return 0;
}
unsigned WINAPI RequestHandler(void* arg)
{
SOCKET hClntSock = (SOCKET)arg;
char buf[BUF_SIZE];
char method[BUF_SMALL];
char ct[BUF_SMALL];
char fileName[BUF_SMALL];
int ret = recv(hClntSock, buf, BUF_SIZE, 0);
if (strstr(buf,"HTTP/")==NULL)
{
SendErrorMSG(hClntSock);
closesocket(hClntSock);
return 1;
}
strcpy(method, strtok(buf, " /"));
if (strcmp(method,"GET"))
SendErrorMSG(hClntSock);
strcpy(fileName, strtok(NULL, " /"));
printf("fileName:%s\n", fileName);
strcpy(ct, ContentType(fileName));
SendData(hClntSock,ct,fileName);
return 0;
}
void SendData(SOCKET sock, char* ct,char* fileName)
{
//發送資料
char protocol[] = "HTTP/1.0 200 OK\r\n";
char servName[] = "Server:simple web server\r\n";
char cntLen[] = "Content-length:2048\r\n";
char cntType[BUF_SMALL];
char buf[BUF_SIZE];
FILE* sendFile;
memset(buf, 0, sizeof(buf));
sprintf(cntType, "Content-type:%s\r\n\r\n",ct);
//printf("---cntType----%s", cntType);
if ((sendFile=fopen(fileName,"r"))==NULL)
{
printf("%s fopen error!\n", fileName);
SendErrorMSG(sock);
return;
}
/* 傳輸頭檔案 */
send(sock, protocol, strlen(protocol), 0);
printf("%s", protocol);
send(sock, servName, strlen(servName), 0);
printf("%s", servName);
send(sock, cntLen, strlen(cntLen), 0);
printf("%s", cntLen);
send(sock, cntType, strlen(cntType), 0);
printf("%s", cntType);
/* 傳輸請求資料 */
while (!feof(sendFile))
{
memset(buf, 0, sizeof(buf));
fgets(buf, BUF_SIZE, sendFile);
send(sock, buf, strlen(buf), 0);
printf("%s", buf);
}
fclose(sendFile);
closesocket(sock);
}
void SendErrorMSG(SOCKET sock)
{
char protocol[] = "HTTP/1.0 400 Bad Request\r\n";
char servName[] = "Server:simple web server\r\n";
char cntLen[] = "Content-length:2048\r\n";
char cntType[] = "Content-type:text/html\r\n\r\n";
char content[] = "<html><head></head><body><font>發生錯誤!查看請求檔案名和請求方式!</font></body></html>\r\n";
send(sock, protocol, strlen(protocol), 0);
printf("%s", protocol);
send(sock, servName, strlen(servName), 0);
printf("%s", servName);
send(sock, cntLen, strlen(cntLen), 0);
printf("%s", cntLen);
send(sock, cntType, strlen(cntType), 0);
printf("%s", cntType);
send(sock, content, strlen(content), 0);
printf("%s", content);
closesocket(sock);
}
char* ContentType(char* file)
{
char extension[BUF_SMALL];
char fileName[BUF_SMALL];
strcpy(fileName, file);
strtok(fileName, ".");
//printf("ContentType function: %s",fileName);
strcpy(extension, strtok(NULL, "."));
if (!strcmp(extension, "html") || !strcmp(extension, "htm"))
{
//printf("text/html\n");
return "text/html";
}
else
{
//printf("text/html\n");
return "text/plain";
}
}
void ErrorHandling(char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
圖1:

圖2:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/226549.html
標籤:C語言
上一篇:求助
下一篇:求大佬幫我看看這道二叉樹問題
