winsock 实现HTTP GET/POST

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了winsock 实现HTTP GET/POST相关的知识,希望对你有一定的参考价值。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "winsock2.h"
#pragma comment(lib,"WS2_32.lib")

int socket_readline(SOCKET socket,char *head) 
{ 
    char c = ‘\0‘; 
    int r = 0,i = 0; 
    while(recv(socket,&c,1,0)>0) 
    {
        if(r == 1) 
        { 
            if(c == ‘\n‘) 
            { 
                break; 
            } 
            else 
            { 
                r = 0; 
            } 
        } 
        else if(c == ‘\r‘) 
        { 
            r = 1; 
        } 
        else head[i++] = c; 
    } 
    head[i] = ‘\0‘; 
    if(strcmp(head,"\r\n") == 0) return -1; 
    else return i; 
} 

int parse_url(char *url,char *host,int *port,char *path,char *data)
{
	char *p = strstr(url,"://");
	if(!p) return -1;
	p += 3;

	int protocal = (int)(p-url);
	protocal = protocal==5?protocal=443:protocal=80;

	char *hostPort = p;
	char *hostPortEnd = strstr(p,"/");
	if(!hostPortEnd) {
		if(strlen(p) < 1) return -1;
		else hostPortEnd = p+strlen(p);
	}
	
	char *hostEnd = strstr(hostPort,":");
	if(!hostEnd){
		*port = protocal;
		hostEnd = hostPortEnd;
	}else{
		*port = (int)atoi(hostEnd+1);
	}
	strncpy(host,hostPort,hostEnd-hostPort);

	char *pathStart = hostPortEnd;
	if(!pathStart) return -1;

	char *pathEnd = strstr(pathStart,"?");
	if(!pathEnd)
		strncpy(path,pathStart,strlen(pathStart));
	else
		strncpy(path,pathStart,pathEnd-pathStart);

	if(pathEnd)
		strncpy(data,pathEnd+1,strlen(pathEnd)-1);
	return 1;
}

const char* strstri(const char* str, const char* subStr)
{
	int len = strlen(subStr);
	if(len == 0)
	{
		return NULL;
	}
	
	while(*str)
	{
		if(strncmp(str, subStr, len) == 0)
		{
			return str;
		}
		++str;
	}
	return NULL;
}

char *ajax_get(char *url)
{
	int port = 0;
	char host[256],path[256],data[256];
	memset(host,0,sizeof(host));
	memset(path,0,sizeof(path));
	memset(data,0,sizeof(data));

	if(!parse_url(url,host,&port,path,data)) return NULL;

	SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(s == INVALID_SOCKET) {
		return NULL;
	}
	
	sockaddr_in servAddr;
	servAddr.sin_family = AF_INET;
	servAddr.sin_port = htons(port);   
	servAddr.sin_addr.S_un.S_addr = inet_addr(host);
	connect(s,(sockaddr*)&servAddr,sizeof(servAddr));

	char *getFormat = 
		"GET %s?%s HTTP/1.1\r\n"
		"Host: %s\r\n"
        "Connection: Keep-Alive\r\n" 
		"\r\n";

	int sendDataSize = strlen(getFormat)+strlen(path)+strlen(data)+strlen(host)+200;
	char *sendData = (char *)malloc(sendDataSize);
	sprintf(sendData,getFormat,path,data,host);
	send(s,sendData,strlen(sendData),0);
	free(sendData);

	char *http_head_recv = new char[3000]; 
    int Content_Length = 0; 
    for(int flag=1;flag>0;) 
    { 
        memset(http_head_recv,0,sizeof(http_head_recv)); 
        flag = socket_readline(s,http_head_recv);

		char key[125],value[2000];
        memset(key,0,sizeof(key)); 
        memset(value,0,sizeof(value));
		sscanf(http_head_recv,"%s%s",key,value);
		key[strlen(key)-1] = ‘\0‘;

        if(strstri(key,"Content-Length") != NULL){ 
			Content_Length = atoi(value);
        }
    }
    free(http_head_recv);

	char *msg = NULL;
	if(Content_Length>0)
    {
        msg = new char[Content_Length+1];
        memset(msg,0,Content_Length+1);
        recv(s,msg,Content_Length,0);
        msg[Content_Length] = ‘\0‘;
    }

	closesocket(s);
	return msg;
}

char *ajax_post(char *url)
{
	int port = 0;
	char host[256],path[256],data[256];
	memset(host,0,sizeof(host));
	memset(path,0,sizeof(path));
	memset(data,0,sizeof(data));
	
	if(!parse_url(url,host,&port,path,data)) return NULL;
	
	SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(s == INVALID_SOCKET) {
		return NULL;
	}
	
	sockaddr_in servAddr;
	servAddr.sin_family = AF_INET;
	servAddr.sin_port = htons(port);   
	servAddr.sin_addr.S_un.S_addr = inet_addr(host);
	connect(s,(sockaddr*)&servAddr,sizeof(servAddr));
	
	char *getFormat = 
		"POST %s HTTP/1.1\r\n"
		"Host: %s\r\n"
        "Connection: Keep-Alive\r\n" 
		"\r\n%s";
	
	int sendDataSize = strlen(getFormat)+strlen(path)+strlen(data)+strlen(host)+200;
	char *sendData = (char *)malloc(sendDataSize);
	sprintf(sendData,getFormat,path,host,data);
	send(s,sendData,strlen(sendData),0);
	free(sendData);
	
	char *http_head_recv = new char[3000]; 
    int Content_Length = 0; 
    for(int flag=1;flag>0;) 
    { 
        memset(http_head_recv,0,sizeof(http_head_recv)); 
        flag = socket_readline(s,http_head_recv);
		
		char key[125],value[2000];
        memset(key,0,sizeof(key)); 
        memset(value,0,sizeof(value));
		sscanf(http_head_recv,"%s%s",key,value);
		key[strlen(key)-1] = ‘\0‘;
		
        if(strstri(key,"Content-Length") != NULL){ 
			Content_Length = atoi(value);
        }
    }
    free(http_head_recv);
	
	char *msg = NULL;
	if(Content_Length>0)
    {
        msg = new char[Content_Length+1];
        memset(msg,0,Content_Length+1);
        recv(s,msg,Content_Length,0);
        msg[Content_Length] = ‘\0‘;
    }
	
	closesocket(s);
	return msg;
}

int main(int argc, char* argv[])
{
	char *myajax_test = "http://10.10.22.102/myajax/test.php?user=admin";

	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2,0);
	WSAStartup(sockVersion, &wsaData);

	char *text = ajax_post(myajax_test);
	if(text)
	{
		printf("%s\n",text);
	}

	WSACleanup();
	return 0;
}

  

以上是关于winsock 实现HTTP GET/POST的主要内容,如果未能解决你的问题,请参考以下文章

Java URLConnection实现HTTP的GET/POST

CURL实现HTTP的GET POST方法

Java 模拟 HTTP Get Post 请求实现论坛自动回帖

GET,POST传值总结

07_android入门_採用HttpClient的POST方式GET方式分别实现登陆案例

java.lang.IllegalStateException: Method get not annotated with HTTP method type (ex. GET, POST);(代码片