#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32")
#define I_GET 0x00000001
#define I_POST 0x00000002
typedef struct web_socket
{
SOCKET socket;
struct sockaddr_in client_in;
WSAEVENT event;
char *buffer;
u_long length;
char *data; //post数据
u_long ul_datalength; //post长度
char *httppath; //请求路径
char *pathparam; //请求路径后面的参数
int i_method; //提交方式
bool b_isConnect; //长连接
}web_socket;
unsigned __stdcall thread_client_web(void*);
int main(int argc, char* argv[])
{
WSADATA WSAData;
WSAStartup(MAKEWORD(2,2),&WSAData);
struct sockaddr_in server_in;
SOCKET sock;
server_in.sin_family = AF_INET;
server_in.sin_port = htons(99);
server_in.sin_addr.s_addr = INADDR_ANY;
sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
bind(sock,(struct sockaddr far*)&server_in,sizeof(server_in));
listen(sock,10);
while(true)
{
web_socket *web = (web_socket*)malloc(sizeof(web_socket));
memset(web,0x0,sizeof(web_socket));
int c_len = sizeof(web->client_in);
web->socket = accept(sock,(struct sockaddr far*)&web->client_in,&c_len);
_beginthreadex(NULL,0,thread_client_web,web,0,NULL);
}
printf("Hello World!\n");
WSACleanup();
return 0;
}
char * __stdcall _thread_client_recv_find_header_key_to_string(char *header,char *key,char *outval)
{
char *find,*find_over;
find = strstr(header,key);
if(find == NULL || (find_over = strstr(find,"\r\n")) == NULL )
return NULL;
else
{
find+=strlen(key);
find++;
memcpy(outval,find,find_over-find);
return outval;
}
}
bool __stdcall _thread_client_recv_find_header_key_bool(char *header,char *key,char *val)
{
char outval[32]={0};
if(_thread_client_recv_find_header_key_to_string(header,key,outval)==NULL)
return false;
else
{
if(strstr(outval,val) != NULL)
return true;
else
return false;
}
}
int __stdcall _thread_client_recv_find_header_key_to_integer(char *header,char *key)
{
char val[32]={0};
if(_thread_client_recv_find_header_key_to_string(header,key,val)==NULL)
return 0;
else
return atoi(val);
}
bool __stdcall _thread_client_recv_post_http_header(web_socket *web)
{
char *t_find=NULL;
if(memcmp(web->buffer,"GET",3)==0)
{
web->i_method = I_GET;
web->httppath = strstr(web->buffer,"GET ");
web->httppath+=strlen("GET ");
}
else if(memcmp(web->buffer,"POST",4)==0)
{
web->i_method = I_POST;
web->httppath = strstr(web->buffer,"POST ");
web->httppath+=strlen("POST ");
web->data+=2;
*web->data = '\0';
web->data = web->data+2;
web->ul_datalength = _thread_client_recv_find_header_key_to_integer(web->buffer,"Content-Length");
}
web->b_isConnect = _thread_client_recv_find_header_key_bool(web->buffer,"Connection","keep-alive");
if(web->httppath == NULL)
return false;
t_find = strstr(web->httppath," ");
if(t_find != NULL)
{
*t_find = '\0';
}
t_find = strstr(web->httppath,"?");
if(t_find != NULL)
{
*t_find = '\0';
web->pathparam = t_find+1;
}
return true;
}
bool __stdcall _thread_client_check_is_recv(web_socket *web)
{
if(web->i_method == 0 )
{
web->data = strstr(web->buffer,"\r\n\r\n");
if(NULL == web->data)
return true;
else
_thread_client_recv_post_http_header(web);
}
if(web->i_method == I_GET)
{
return false;
}
else if(web->i_method == I_POST)
{
if(web->ul_datalength == strlen(web->data))
return false;
}
return true;
}
unsigned __stdcall thread_client_web_send(web_socket *web)
{
if(web->i_method == I_GET)
printf("RECV:%d\n%s:%s\n",web->length,web->httppath,web->pathparam);
else if(web->i_method == I_POST)
printf("RECV:%d\n%s:%s\n%s\n",web->length,web->httppath,web->pathparam,web->data);
char t[]="aaaaa";
char buff[512]={0};
sprintf(buff,"http/1.0 200 ok\r\nContent-Length:%d\r\nConnection:Keep-Alive\r\n\r\n%s",strlen(t),t);
send(web->socket,buff,strlen(buff),0);
return 1;
}
unsigned __stdcall thread_client_web(void* param)
{
#define PAGE_SIZE 0x2000
bool isRecvOver;
web_socket *web = (web_socket*)param;
web->event = WSACreateEvent();
web->buffer = (char*)malloc(PAGE_SIZE*10);
WSAEventSelect(web->socket,web->event,FD_READ|FD_CLOSE);
WSANETWORKEVENTS networkevent;
u_long cRecv;
web_loop_next:
isRecvOver=true;
memset(web->buffer,0x0,PAGE_SIZE*10);
web->length=0;
web->b_isConnect = true;
web->i_method=0;
web->data=NULL;
web->httppath=NULL;
web->pathparam=NULL;
while(isRecvOver)
{
WaitForSingleObject(web->event,INFINITE);
WSAEnumNetworkEvents(web->socket,web->event,&networkevent);
if(networkevent.lNetworkEvents & FD_READ)
{
ioctlsocket(web->socket,FIONREAD,&cRecv);
web->length += recv(web->socket,web->buffer+web->length,cRecv,0);
isRecvOver = _thread_client_check_is_recv(web);
}
else if(networkevent.lNetworkEvents & FD_CLOSE)
{
closesocket(web->socket);
isRecvOver=false;
web->b_isConnect=false;
goto _exit;
}
}
thread_client_web_send(web);
// if(web->b_isConnect)
goto web_loop_next;
_exit:
printf("over");
free(web->buffer);
free(web);
return 0;
}
分享到:
相关推荐
此代码用c++实现了http客户端的编写,其中包括了多字节转utf8(已在ExecuteRequest函数中实现,不用再引用所给的编码转换),get和post两种请求方式,后面有json数据的解析以及实现,详情可去博客...
C++开发基于TCPsocket实现的web服务器源码。基于TCP socket实现的支持报文解析并返回响应报文的Web服务器,可以响应多种文件需求并能够处理特定的错误情况 服务器实现及其功能: 1、读取配置文件,为服务器自身设置...
在windows平台下使用C++,MFC框架实现了FTP协议的服务端程序。支持客户端的文件下载,上传,删除等常用FTP命令的响应。使用多线程技术,允许多个客户端同时连接。实时记录显示服务器和客户端交互的状态变化。支持...
C++实现客户端与服务器TCP连接,上传,下载,执行指定exe文件,获取目录等功能,平台vs2017可直接运行sln文件。(输入help可查看有哪些指令)
简单tcp socket 客户端 服务端代码实现 附C++代码源码
一个基于C++实现的完整进行FTP应用管理的 Server服务器源码例子
该项目是在linux下采用C/C++编程,基于TCP协议,服务器端采用多进程长连接的socket的通信方式,并采用开源的负载均衡器G6作为客户端请求与服务端响应的中间件分发器。考虑到服务器端如果每接收到一个请求fork一个...
MINIO服务器基于AWS S3 SDK 文件上传及下载(C++实现类)
(牛客网C++课程)Linux 高并发Web服务器项目实战(带定时检测代码) 技术框架: 1. 线程池 + 非阻塞 socket + epoll + 事件处理的并发模型 2. 状态机解析HTTP请求 3. 心跳机制 4. 简易日志系统 主要内容: 1. ...
C++语言编写,SOCKET套接字通信,分服务器和客户端,多线程模型,Win32控制台。 首先聊天室分为服务端和客户端,通过TCP连接通信。运行顺序为: 1.首先打开服务服; 2.打开客户端,用户输入名字,连接到服务端后...
首先要理解基本的原理,2台电脑间实现TCP通讯,首先要建立起连接,在这里要提到服务器端与客户端,两个的区别通俗讲就是主动与被动的关系,两个人对话,肯定是先有人先发起会话,要不然谁都不讲,谈什么话题,呵呵!...
* 连接池中包括数据库服务器连接对应的IP,端口,用户,密码等信息 * 对数据库对象存入`STL`当中,需要设置最大值,最小值限制队列 * 多线程从连接池中取出数据库对象若有取出,`没有等待`调用算法 * 对 连接池中的...
**C语言HTTP服务器实现源码** 本资源提供了一个基于C语言的HTTP服务器实现源码,允许用户在网络中创建并管理自己的Web服务器。此项目源码不仅适用于学习目的,还可作为实际应用的起点,支持二次开发和定制。 该...
一个socket对应多个client,每个socket开启一个新的线程。可直接使用。
实现实现客户端和服务器的连接,里面有Debug文件,cpp文件
**本项目实现了基于Epoll管理连接、基于定时器处理非活动连接、基于线程池实现Reactor模式、基于cgi脚本处理http请求结果的HTTP服务器。主要框架如下:**\ ![](./image/newhttpd.jpg) 2、模块介绍 **1)主线程...
websocket c++服务器,浏览器握手成功
Windows环境下的c++程序,客户机和服务器程序在编译后,均以命令行的方式执行。 服务器程序执行时可以带一个命令行参数,使用来接受请求的监听套接字的协议端口号。这个参数是可选的。如果不指定端口号,代码将使用...
客户端向服务器端发送一个消息后,服务器端向客户端反馈收到消息的时间和内容,建立连接后客户端可多次向服务器端发送消息
C++(Socket)实现的TCP协议的多线程例子,允许多个客户端连接