Linux C uses the socket for HTTP communication and receives HTTP responses of any size (iv)

Source: Internet
Author: User
Tags setcookie

Finally speaking of the socket here. The actual socket for HTTP communication is the use of the socket to send HTTP request information to the HTTP server, and then use the socket to receive HTTP responses.

Because the server with which this article communicates is known as IP, there is another way to be able to communicate with an Internet site in HTTP.

The code is as follows:

(1) Http.h

Declarations of functions that may be locked by other programs in HTTP.C
#include "http_url.h"
#ifndef Http_h
#define Http_h
typedef struct SOCKADDR_IN IP;
typedef struct SOCKADDR *ip;
extern Char cookie[200];
extern int Create_socket ();
extern void Init_ip (IP *httpip,char *ip,int port);
extern int Bind (int socket,ip *httpip);
extern int Get_other_socket (int socket);
extern int Connect (int socket,ip* httpip);
extern int Send (int socket,char *data);
extern char* Read (int socket);
extern int Http_perform_url (PURL url,char **buffer);
extern int Find_cookie (char *cookie,char *httpbuffer);
extern void Randomcode (char *result);
extern void Set_cookie (char *cookie_);
extern void Httpbuffer_free (char **respond);
#endif//Http_h

(2) Http.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include "http_url.h"//Add HTTP_HRL module
#include "data2.h"//Join DATA2 module, DATA2 module for storing and processing HTTP responses
#define Setcookie "Set-cookie:"
#define SENDSIZE 4096//The size of each data sent, note: not used

#define Http_h
NOTE: All defined functions in this file are only suitable for HTTP communication----Exclude certain exception functions
Storage IP with sockaddr_in, struct sockaddr * struct
typedef struct SOCKADDR_IN IP;
typedef struct SOCKADDR *ip;

Global variable cookie, note: Only one cookie is currently supported
Char cookie[200];

int Is_respond_ok (char *httpbuffer);

Customizing functions for creating sockets
Return value: Successfully returned socket nested word, failed return-1
int Create_socket ()
{
int temp;
Temp=socket (af_inet,sock_stream,0);
return temp;

}

Customizing functions that initialize the IP structure body
Parameter one: pointer to the IP struct that will be initialized
Parameter two: Specific IP, for example: 192.167.6.5
Parameter three: Communication port, HTTP communication should pass in 80
void Init_ip (IP *httpip,char *ip,int port)
{
memset (httpip,0,sizeof (*HTTPIP));
httpip->sin_family=af_inet;
HTTPIP-&GT;SIN_ADDR.S_ADDR=INET_ADDR (IP);
Httpip->sin_port=htons (port);
}

Customizing functions that Bind sockets and IP
Parameter one: socket nested word
Parameter two: Pointer to an already initialized IP struct
Return value: Success returns 0, failure returns-1, the cause of the error is stored in errno
int Bind (int socket,ip *httpip)
{
int ret;
Ret=bind (socket, (IP) httpip,sizeof (HTTPIP));
return ret;
}

Customize functions that block waiting for other sockets to connect through accept
Parameter one: socket nested word to be blocked
Return value: Another socket socket that has other sockets connected to the blocked socket that is returned and communicated by the blocked socket
int get_other_socket (int socket)
{
IP otherip;
int temp;
socklen_t length;
Length=sizeof (Otherip);
Temp=accept (socket, (IP) &otherip,&length);
return temp;

}


Customizing the Connect function
Parameter one: client's own socket
Parameter two: pointer to the IP struct that will be connected
Return value: Success returns 0, failure returns-1, the cause of the error is stored in errno
int Connect (int socket,ip* httpip)
{
int flag;
Flag=connect (socket, (IP) httpip,sizeof (*HTTPIP));
return flag;
}


Custom Send Functions
Parameter one: The socket of your own program
Parameter two: The data that will be sent
Return value: greater than or equal to zero to send some or all of the data, failed to return 1, the cause of the error is stored in errno
To be modified: because the Write function may not be finished at one time, you may need to modify the function to send multiple times??????????????????? If I have not modified, please continue to change the brave later
int Send (int socket,char *data)
{
int ret=1;
/* int sendlength=0,datalength=0;

while (ret!=0)
{}
*/

Ret=write (Socket,data,strlen (Data));
return ret;
}

Customizing the Read function
Parameter one: The socket of your own program
Return value: Successfully returns a pointer to the dynamic memory that stores the corresponding content, failure returns null
Note: 1) The dynamic memory pointer returned should be released by free when not in use; 2) If there is no real problem, please do not move, if the reading data problems, please check the DATA2.C function
char* Read (int socket)
{
int length=0,return_length;
Char buffer[1024];
Char *data;
Pbuffer Header,nowbuffer;//nowbuffer pointing to the buffer node being used


if (null!= (Header=create_emptybufferlink ()))//Create Buffer header
{
if (null== (header))//Create Buffer node for first storage response
{
printf ("\nappend_buffer_node () fail in http.c Read () \ n");//node add failed to return directly
Free_buffer_link (header);
return NULL;
}

}else
{
printf ("\ncreate_emptybufferlink () fail in http.c Read () \ n");//Header node creation failed to return directly
return NULL;
}

Each read 1024 nodes are stored in buffer and then copied to the buffer node by strncpy
while ((Return_length=read (socket,buffer,1024)) >0)
{
if (return_length==-1)
{
printf ("\nreceive wrong!\n");
Free_buffer_link (header);
Header=null;
return NULL;
}else
{

if (length>=50176)//If the node is already full, create a new node and save the content to the newly established node
{
nowbuffer->data[length]= ' + ';
if (null== (Nowbuffer=append_buffer_node (header)))
{
printf ("\nappend_buffer_node () fail in http.c Read () \ n");//node add failed to return directly
Free_buffer_link (header);
return NULL;
}
length=0;
strncpy (nowbuffer->data+length,buffer,return_length);
Length+=return_length;
}
Else
{
strncpy (nowbuffer->data+length,buffer,return_length);
Length+=return_length;
}
}

}

nowbuffer->data[length]= ' + ';
Data=get_all_buffer (header);//The contents of the Buffer list are taken out and stored in dynamic memory

Releasing the buffer linked list
if (header!=null)
{
Free_buffer_link (header);
Header=null;
}

if (length==0)
{
printf ("No date receive!\n");
return NULL;
}

Return data;//Returns a pointer to the dynamic memory that stores the response content (possibly empty)
}

For HTTP communication
Parameter one: IP for HTTP communication, such as 192.168.6.1
Parameter two: Data sent to HTTP server
Parameter three: pointer to the variable that stores the HTTP response content pointer, if not understood, refer to dynamic memory transfer between functions
Return value: Successfully returned 1, failed to return 0
Note: Dynamic memory must be freed
int Http_perform (char *ip,char *datasend,char **buffer)
{

int Client_socket_word;
IP httpip;

if ( -1== (Client_socket_word=create_socket ()))
{
Perror ("Http.c create_socket () fail");
return 0;
}


INIT_IP (&httpip,ip,80);

if ( -1==connect (CLIENT_SOCKET_WORD,&AMP;HTTPIP))
{
Perror ("Http.c Connect () fail");
return 0;
}


if ( -1==send (client_socket_word,datasend))
{
Perror ("Http.c Send () fail");
return 0;
}


*buffer=read (Client_socket_word);

if (Null==buffer)
{
Perror ("Http.c Read () fail");
return 0;
}

if ( -1!=client_socket_word)
{
Close (Client_socket_word);
return 1;
}

return 0;
}

HTTP communication via struct URL
Parameter one: A structure that stores communication information
Parameter two: The address of the dynamic pointer that stores the HTTP response, which must be freed after use, and must be checked for NULL before use (even if IS_RESPOND_OK () fails, it is still possible for dynamic memory to store information that has failed to respond)
Return value: Successfully returned 1, failed to return 0
Note: Regardless of success or failure, dynamic memory really must be released!!!
int Http_perform_url (PURL url,char **buffer)
{
Char host[100];
Char path[500];
Char request[10*1024];//almost forgot you.

memset (Request, ' n ', 10*1024*sizeof (char));

if (1==http_request (Request,url))
{
if (1==parse_url (Host,path,url->url))
{

if (1==http_perform (Host,request,buffer))
{
if (Null!=buffer)
{
if (1==IS_RESPOND_OK (*buffer))
{
return 1;
}
}
}


}
}

return 0;
}

Intercepts a string between two pointers
Parameter one: A pointer to the beginning of a string
Parameter two: Pointer to end of string
Return value: Successfully returned 1, failed to return 0
int Str_between (char* result,char *pstart,char *pend)
{
Char *result_,*pstart_;
Result_=result;
Pstart_=pstart;

if ((Pstart) && (pEnd) && (Pend>pstart))
{
while ((Pstart_)!=pend)
{
* (Result_) =* (Pstart_);
pstart_++;
result_++;

}
}else
{
return 0;
}
* (result_) = ' + ';
return 1;
}

Search for cookies from HTTP responses
Parameter one: A pointer that stores a cookie string
Parameter two: Httpbuffer for storing cookies
int Find_cookie (char *cookie,char *httpbuffer)
{
Char *pstart,*pend,*temp;
if ((Strstr (Httpbuffer,setcookie)!=null))
{
Temp=strstr (Httpbuffer,setcookie);
Pstart=temp+sizeof (Setcookie);
pstart--;
}

if ((Temp=strstr (Httpbuffer, "; path"))!=null)
{
Pend=temp;
}

if (! ( (Pstart) && (pEnd)))
{
return 0;
}

if (Str_between (cookie,pstart,pend))
{
printf ("%s\n", cookies);
return 1;
}
Else
{
return 0;
}

}

When you want to set a cookie yourself, you can use this function to copy a custom cookie into a global variable.
Parameter one: A cookie string, such as: "Synsnd=hdh38rhy3gdyug873gdyguwsgdipo39yrdh"
void Set_cookie (char *cookie_)
{
if (cookie_)
{
strcpy (Cookie,cookie_);
}

}

Determine if the response is successful by checking whether there are "302 Found" and "OK" in the Httpbuffer
Parameter 1:httpbuffer
Return value: Successfully returned 1, failed to return 0
int Is_respond_ok (char *httpbuffer)
{
if ((Strstr (Httpbuffer, "302 Found")) | | (Strstr (Httpbuffer, "OK"))
{
printf ("Respond ok!\n");
return 1;
}
Else
{
printf ("Respond wrong!\n");
return 0;

}
}

Generates a string of random numbers with a length of approximately 16-19
Parameter one: A string pointer used to store a random number string
To be modified: I do not set the return value and error correction mechanism, as long as the large enough to accept the string, generally do not error
void Randomcode (char *result)
{
int i;
Char temp1[20],temp2[20];
Srand ((unsigned int) time (NULL));
I=rand ();
Num_to_string (Temp1,i);
I=rand ();
Num_to_string (Temp2,i);

strcpy (RESULT,TEMP1);
strcat (RESULT,TEMP2);
}

When the HTTP response is not empty, the dynamic memory used to free the storage response
void Httpbuffer_free (char **respond)
{
if (*respond!=null)
{
Free (*respond);
*respond=null;//should be *respond=null instead of respond=null, changing the pointer stored in respond
}
}

The next article puts the use example.

Linux C uses the socket for HTTP communication and receives HTTP responses of any size (iv)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.