Linux平台C语言通过http协议POST JSON数据

前言

JSON数据格式是http协议POST传输方式中的一种。

目录

  • 常见的HTTP/1.1请求数据
  • POST JSON数据

C代码

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <malloc.h>
#include <math.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include "cJSON/cJSON.h"

/*
POST /.../... HTTP/1.1
Host: ...:...
Connection: keep-alive
Content-Type: application/json; charset=UTF-8
Content-Length: 78

{
    ...
}
*/

// POST JSON数据
HttpResponse *postJson(const char *ip, int port, const char *subUrl, const char *jsonStr) {
    //LOGD("postJson(): IP= %s , PORT= %d , SUB_URL= %s , JSON= %s", ip, port, subUrl, jsonStr);
    
    HttpResponse *_httpResponse = (HttpResponse *) malloc(sizeof(HttpResponse));
    memset(_httpResponse, 0, sizeof(HttpResponse));
    _httpResponse->code = strdup("500");

    int _sockfd;
    int _len;
    struct sockaddr_in _address;
    int _ret;
    char *_sendStr = (char *) malloc(1024 * 1024);
    memset(_sendStr, 0, 1024 * 1024);
    char _str1[1024] = {0};
    char *_recvStr = (char *) malloc(1024 * 1024);
    memset(_recvStr, 0, 1024 * 1024);

    _sockfd = socket(AF_INET, SOCK_STREAM, 0);
    _address.sin_family = AF_INET;
    _address.sin_addr.s_addr = inet_addr(ip);
    _address.sin_port = htons(port);

    // 超时时间设置
    struct timeval _tm;
    _tm.tv_sec = 0;
    _tm.tv_usec = 500000;
    // 设置发送超时
    setsockopt(_sockfd, SOL_SOCKET, SO_SNDTIMEO, &_tm, sizeof(struct timeval));
    // 设置接收超时
    setsockopt(_sockfd, SOL_SOCKET, SO_RCVTIMEO, &_tm, sizeof(struct timeval));

    _len = sizeof(_address);
    _ret = connect(_sockfd, (struct sockaddr *) &_address, _len);
    if (_ret < 0) {
        //LOGE("postJson(): connect ERROR, ERROR= %s, IP= %s , PORT= %d", strerror(errno), ip, port);
        free(_sendStr);
        _sendStr = NULL;
        free(_recvStr);
        _recvStr = NULL;
        return _httpResponse;
    }

    strcpy(_sendStr, "");
    strcat(_sendStr, "POST ");
    strcat(_sendStr, subUrl);
    strcat(_sendStr, " HTTP/1.1\r\n");
    strcat(_sendStr, "Host: ");
    strcat(_sendStr, ip);
    strcat(_sendStr, ":");
    sprintf(_str1, "%d", port);
    strcat(_sendStr, _str1);
    strcat(_sendStr, "\r\n");
    strcat(_sendStr,"Connection: keep-alive\r\n");
    strcat(_sendStr, "Content-Type: application/json; charset=UTF-8\r\n");
    strcat(_sendStr, "Content-Length: ");
    _len = strlen(jsonStr);
    sprintf(_str1, "%d", _len);
    strcat(_sendStr, _str1);
    strcat(_sendStr, "\r\n\r\n");
    // jsonStr的值为post的数据
    strcat(_sendStr, jsonStr);

    _len = write(_sockfd, _sendStr, strlen(_sendStr));
    //LOGD("postJson(): write LENGTH= %d", _len);

    int _readSize = 0;
    while (1) {
        _len = read(_sockfd, _str1, 1024);
        //LOGD("postJson(): read LENGTH= %d", _len);
        if (_len <= 0) {
            break;
        }

        memcpy(_recvStr + _readSize, _str1, _len);
        _readSize += _len;

        // 超时时间设置,后续包耗时较小
        _tm.tv_sec = 0;
        _tm.tv_usec = 10000;
        // 设置接收超时
        setsockopt(_sockfd, SOL_SOCKET, SO_RCVTIMEO, &_tm, sizeof(struct timeval));
    }

    free(_sendStr);
    _sendStr = NULL;

    close(_sockfd);

    if (strlen(_recvStr) == 0) {

    } else {
        releaseHttpResponse(_httpResponse);
        _httpResponse = parseResponse(_recvStr);
    }

    free(_recvStr);
    _recvStr = NULL;

    return _httpResponse;
}

觉得有用的话,可以给我点奖励哦!(微信)
在这里插入图片描述

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lichaofan2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值