c++winsock多线程http服务器
c++ winsock multithread http server
我是C++的新手,遇到了一个问题,当我连接到服务器(使用浏览器)时,它会发送一个响应,并且在浏览器上显示得很好,但查看它发送网页两次的控制台,页面视图计数器会确认这一点,通过测试,我不确定它的运行顺序。
循环侦听新连接:
while (true){
//create temp scoket for cconnetcion
SOCKET ClientSocket;
ClientSocket = INVALID_SOCKET;
// Accept the socket from the client when it tries to connect
ClientSocket = accept(ListenSocket, NULL, NULL);
printf("NEWCON" );
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed: %dn", WSAGetLastError());
std::string blah;
std::cin >> blah;
closesocket(ListenSocket);
WSACleanup();
return 104;
}
views += 1;
AfxBeginThread(RequestProsorses, (LPVOID)ClientSocket);
}
RequestProsorses函数:
UINT RequestProsorses(LPVOID pParam){
printf("n NEWREC");
SOCKET ClientSocket = (SOCKET)pParam;
#define DEFAULT_BUFLEN 512
char recvbuf[DEFAULT_BUFLEN];
int conResult, iSendResult;
int recvbuflen = DEFAULT_BUFLEN;
std::string returnVal = "HTTP/1.x 200 OK n Transfer-Encoding: chunked nn <html><body><b>Total Page Views:</b>";
conResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (conResult > 0) {
printf("Bytes received: %dn", conResult);
//create response to user
returnVal += std::to_string(views) + "</body></html>";
//printf(returnVal.c_str());
// Send Responce to user
iSendResult = send(ClientSocket, returnVal.c_str(), returnVal.length(), 0);
if (iSendResult == SOCKET_ERROR) {
//printf("send failed: %dn", WSAGetLastError());
std::string blah;
std::cin >> blah;
closesocket(ClientSocket);
WSACleanup();
}
printf("Bytes sent: %dn", iSendResult);
}
else if (conResult == 0){
printf("Connection closing...n");
}
else {
printf("recv failed: %dn", WSAGetLastError());
std::string blah;
std::cin >> blah;
closesocket(ClientSocket);
WSACleanup();
}
// shutdown the send half of the connection since no more data will be sent
conResult = shutdown(ClientSocket, SD_SEND);
if (conResult == SOCKET_ERROR) {
printf("shutdown failed: %dn", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
}
closesocket(ClientSocket);
return 0;
}
控制台输出(仅从一个视图):
NEWCONNEWCON
NEWREC
收到的NEWRECBytes:373
发送的字节数:99
接收的字节数:287
发送的字节数:99
希望这对你来说是足够的信息,如果不是,我当然很乐意发布更多。
if语句检查头端
for (int i = 0; i <= recvbuflen; i++){
if (recvbuf[i] == 'n' && (int)recvbuf[i + 1] == -52){
finished = true;
}
}
我找到了答案:),感谢@JoachimPileborg和@MartinJames的帮助!简单地说,浏览器发送了第二个请求,由于程序不检查正在查看的页面(无论此时发生什么,它都只是发送相同的页面),在我看来,它只为一个页面请求做了两次相同的事情。浏览器也在尝试评估/favicon.ico。
我已经对代码进行了更改,虽然还没有完成,但它仍然有效,所以如果有人对我所做的更改感兴趣,这里是代码(以防我在没有意识到的情况下修复了其他错误)。
// HTMLtest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <string>
#include <iostream>
#include <thread>
#include <afxwin.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
int views = 0;
UINT RequestProsorses(LPVOID pParam){
printf("n NEWREC");
SOCKET ClientSocket = (SOCKET)pParam;
#define DEFAULT_BUFLEN 512
char recvbuf[DEFAULT_BUFLEN];
int conResult, iSendResult;
int recvbuflen = DEFAULT_BUFLEN;
std::string returnVal = "HTTP/1.x 200 OK n Transfer-Encoding: chunked nn <html><body><b>Total Page Views:</b>";
bool finished = false;
do {
std::cout << "b";
conResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
for (int i = 0; i <= recvbuflen; i++){
if (recvbuf[i] == 'n' && (int)recvbuf[i + 1] == -52){
finished = true;
}
}
if (conResult > 0) {
}
else if (conResult == 0){
printf("Connection closing...n");
}
else {
printf("recv failed: %dn", WSAGetLastError());
std::string blah;
std::cin >> blah;
closesocket(ClientSocket);
}
} while (conResult > 0 && finished == false);
printf("Bytes received: %dn", conResult);
std::cout << "RECIVED: " << recvbuf;
//create response to user
returnVal += std::to_string(views) + "</body></html>";
//printf(returnVal.c_str());
// Send Responce to user
iSendResult = send(ClientSocket, returnVal.c_str(), returnVal.length(), 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed: %dn", WSAGetLastError());
std::string blah;
std::cin >> blah;
closesocket(ClientSocket);
}
printf("Bytes sent: %dn", iSendResult);
closesocket(ClientSocket);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
// Initialize Winsock
int IPresult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (IPresult != 0) {
printf("WSAStartup failed: %dn", IPresult);
return 1;
}
struct addrinfo *result = NULL, *ptr = NULL, params;
ZeroMemory(¶ms, sizeof(params));
params.ai_family = AF_INET;
params.ai_socktype = SOCK_STREAM;
params.ai_protocol = IPPROTO_TCP;
params.ai_flags = AI_PASSIVE;
//resolve the IP address and port to used by the server
IPresult = getaddrinfo(NULL, "80", ¶ms, &result);
if (IPresult != 0) {
printf("getaddrinfo failed: %dn", IPresult);
std::string blah;
std::cin >> blah;
WSACleanup();
return 100;
}
SOCKET ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("Error at socket(): %ldn", WSAGetLastError());
std::string blah;
std::cin >> blah;
freeaddrinfo(result);
WSACleanup();
return 101;
}
// Setup the socket for HTTP
IPresult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (IPresult == SOCKET_ERROR) {
printf("bind failed with error: %dn", WSAGetLastError());
std::string blah;
std::cin >> blah;
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 102;
}
//Free the memory allocated by "getadderinfo" as its no longe needed
freeaddrinfo(result);
if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
printf("Listen failed with error: %ldn", WSAGetLastError());
std::string blah;
std::cin >> blah;
closesocket(ListenSocket);
WSACleanup();
return 103;
}
while (true){
//create temp scoket for cconnetcion
SOCKET ClientSocket;
ClientSocket = INVALID_SOCKET;
// Accept the socket from the client when it tries to connect
ClientSocket = accept(ListenSocket, NULL, NULL);
printf("NEWCON" );
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed: %dn", WSAGetLastError());
std::string blah;
std::cin >> blah;
closesocket(ListenSocket);
WSACleanup();
return 104;
}
views += 1;
AfxBeginThread(RequestProsorses, (LPVOID)ClientSocket);
}
// cleanup
//closesocket(ClientSocket);
WSACleanup();
return 0;
}
很抱歉它太不整洁了:/
相关文章:
- 如何在C++中使用带有SFML的http reqest从节点.js服务器获取数据?
- 在 MySQL 中运行 HTTP 服务器以从客户端接收数据
- boost beast websocket服务器也接受http连接
- 我不明白异步操作如何使HTTP服务器并发
- 将文件发送到 HTTP 服务器 (C++ Wininet)
- 从主机向在VirtualBox linux机器上运行的服务器发送http请求
- 浏览器将随机HTTP消息正文发送到我的boost.asio服务器.我可以更改此设置吗?
- boost::asio http 服务器无法向 Postman 返回有效响应
- 如果C/C Python3扩展托管HTTP服务器并将Python代码称为请求处理程序,则如何处理并发
- 有没有人知道如何终止ESP8266 http Web服务器/接入点
- 为什么这C++ASIO,当执行HTTP / SSL请求时,BEAST服务器会进入错误状态
- QT-简单的HTTP服务器
- Apache HTTP服务器 - 如何在模块上打印到控制台
- web服务器如何知道何时完全接收到HTTP请求
- 使用C HTTP请求将文件上传到服务器
- Windows HTTP服务器API HTTPS服务器
- 在多线程HTTP服务器中发送后,如何干净地关闭套接字
- Boost Asio 示例 HTTP 服务器 -- 以这个例子为例,让它变得"production ready"
- AJAX与C HTTP服务器断开连接
- 使用带有gsoap代理类的gsoap独立服务器实现http-get