利用socket发送http的get与post的实现
实现socket与服务端的连接
get的实现
- 利用http是通过socket连接的原理,进行http功能在C语言中通过socket接口实现
- 通过socket发送请求头与接受返回数据
get请求与返回数据的接受
void error(const char *msg)
{
perror(msg);
exit(1);
}
int create_socket()
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
error("Error opening socket");
}
printf("socketfd: %d \r\n", sockfd);
return sockfd;
}
void close_socket(int sockfd)
{
if (sockfd >= 0)
{
close(sockfd);
}
}
void send_http_get_request(int sockfd, const char *host, const char *path)
{
char request[MAX_SIZE];
snprintf(request, sizeof(request), "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", path, host);
printf("%s \r\n", request);
// 发送get请求
if (write(sockfd, request, strlen(request)) < 0)
{
error("Error writing to socket");
}
printf("send request\r\n");
}
void receive_http_response(int sockfd)
{
char response[MAX_SIZE];
ssize_t n = 0;
while ((n = read(sockfd, response, sizeof(response) - 1)) > 0)
{
response[n] = '\0';
// get 请求返回的数据
printf("response: %s\r\n", response);
}
if (n < 0)
{
error("Error reading from socket");
}
}
主函数
// 域名或IP地址连接
#define domain 1
#if domain
// 域名情况下的与服务端建立socket连接
const char *host = "www.domin.com";
const char *path = "/socket/main";
int port = 80;
// 设置服务器地址
struct sockaddr_in server_addr;
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&server_addr.sin_addr.s_addr, server->h_length);
server_addr.sin_port = htons(port);
#else
const char *host = "192.168.3.1";
const char *path = "/socket/main";
int port = 80;
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
inet_pton(AF_INET, host, &(server_addr.sin_addr));
#endif
// 创建socket
int sockfd = create_socket();
// 连接到服务器
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
error("Error connecting");
}
// 发送HTTP get请求
send_http_get_request(sockfd, host, path);
// 接收并打印HTTP响应
// receive_http_response(sockfd);
// 关闭socket
close_socket(sockfd);
return 0;
需要的头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
post的实现
在上面的get的基础上进行了一定的修改,实现了post的功能
在此使用的body数据格式为json数据,可以更具自己的情况进行一定的修改
- post的请求函数,通过socket发送url,与body
void send_http_post_request(int sockfd, const char *host, const char *path, const char *body) {
char request[MAX_SIZE];
// 注意数据
sprintf(request, "POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Type: application/json\r\n"
"Content-Length: %ld\r\n"
"\r\n"
"%s",
path, host, strlen(body), body);
if (write(sockfd, request, strlen(request)) < 0) {
error("Error writing to socket");
}
}
与上面get的区别仅仅只有path进行了一定的接口和增加了json格式的body数据
const char *path = "/socket/main/post";
char *body= malloc(256);
sprintf(body, "{"
"\"name\":\"%s\","
"\"id\":%d,"
"\"age\":%d"
"}",
name,id,age);
// 发送HTTP post请求
send_http_post_request(sockfd, host, path, (const char *)data);
// 接收并打印HTTP响应
receive_http_response(sockfd);
// 接收数据