- #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;
- }
http服务器长连接的实现
最新推荐文章于 2019-10-16 14:01:05 发布