一个用socket发送http数据的问题

          前一段时间,做过一个项目,我这边是客户端,需要把数据实时的传到服务器上去,使用的协议是http;之前一直认为,通过socket向服务器发送数据

是一件很简单的事情,只要两边把协议定好,一般不会出什么问题;但这个项目,彻底颠覆了我之前的这个认识;

       这个项目中,和服务通信之前,需要先登录一下服务器,这里所谓的登录,其实就是按照固定的格式发送一些数据;这个很简单,服务器登录成功了,

但是后面向服务器发送数据后,却收不到服务器的响应消息;read函数返回的字节数为0;这不是很奇怪吗?检查代码,也没有发现问题,很困惑;第二天和

服务器那边沟通,他们说,他们用postman测试是好的,登录ok,发送数据也ok;这下提示了我,原来,客户端和服务器之间采用的是短连接;登录成功后,

需要断开连接;有数据发送时,在建立连接,发送数据;发送完毕,再断开连接;实际工程中,采用短连接还是长连接,需要双方协定,这次也没有和服务器

确认,就默认了长连接,才导致了这个问题;

     现在数据可以发送了,服务器有回复了,但是,返回错误,服务器端说是不能解析上传的数据;这个项目,客户端向服务器上传数据时,使用http协议,

采用http的multipart/form-data格式来发送数据;就是可以传输多个部分的数据,每个部分的数据格式可以不同;http规定各个部分的数据通过分割符boundary来隔开;

--Boundary\r\n

Content-Disposition\r\n

Content-type\r\n

Data\r\n

--Boundary\r\n

Content-Disposition\r\n

Content-type\r\n

Data1\r\n

--Boundary--\n

最后是以Boundary结束

下面是我发送的数据:

检查了格式,没有发现什么问题,网上百度,也都是这么写的,但到我这,就是有问题,服务器不认!郁闷、困惑。。。

        第二天,想了一个办法,那就是用postman发送数据,通过wareshark抓包,看看它的数据格式怎么写的;

等抓完包,发现,除了个别字段外,也没有什么不同呀,postman发出的包里面的user-agent字段和我的不同,其他的也一样啊。

难道server还管数据是通过什么工具发出来的?不会呀。

      实在没办法了,只能才起hex数据对比了!我采用了和postman相同的boundary,抓取了log,从content-Type字段开始,

一个字节一个字节的和postman比,到boundary这个地方,发现对不上了,刚在拷贝时,还在计算字符个数呢,怎么不对了呢?

再次对比,发现了问题,数据里面有多个boundary,把他们放到一块一比,一切都明白了!

 boundary出现在三个地方,第一个地方是在header部分:

Content-Type:multipart/form-data; boundary=myboundary\r\n

第二个地方是各部分数据的边界地方;

--myboundary\r\n

第三个地方是,所有数据结束的地方:

--myboundary--\r\n

可以看到,这个三个地方boundary的写法是有所不同的,第二部分比第一部分前面多了两个“-”;第三个地方的末尾也多了两个“-”;类似这个

boundary=myboundary

的情况,好像也没有什么,一目了然,但对于类似

boundary= --------------------------693106696888796587382791

的情况,那么这三个地方的区别就不那么明显了!

        原来是这样!立马改代码,再次测试,ok!

  下面附上这一段代码,也许有人会用得着;

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "clt_tcp.h"

#define my_log printf
#define my_printf printf

#define u8 unsigned char

void print_hex(u8* dat_buf, int dat_buf_len)
{
    int i = 0; 

    my_printf("\ndat_len:%d \n", dat_buf_len);
    for(i = 0; i<dat_buf_len; i++) 
    {    
        if(0 == i%16)
        {
            my_printf(" \n");
        }
        my_printf(" %02x", dat_buf[i]);
    }    
    my_printf(" \n");
}


int main(int argc, char *argv[])
{
#define REQ_HEAD_POST "POST /upload.ashx HTTP/1.1\r\n"
#define REQ_HEAD_HOST "Host: healthgw.test.com.cn\r\n"
#define REQ_HEAD_CLOSE "Connection: close\r\n"
#define REQ_HEAD_AGENT "User-Agent: FL_V1\r\n"
#define REQ_HEAD_CONT_TYPE "Content-Type: multipart/form-data; boundary=--------------------------693106696888796587382791\r\n"
#define REQ_DAT_CONT_TYPE "Content-Type: text/plain:charset=UIF-8\r\n"

#define REQ_HEAD_BOUNDARY "----------------------------693106696888796587382791\r\n"
#define REQ_HEAD_CONT_DISPOSIT_FILE "Content-Disposition: form-data; name=\"file\"; filename=\"\"\r\n\r\n\r\n"
#define REQ_HEAD_CONT_DISPOSIT_TEXT "Content-Disposition: form-data; name=\"key\"\r\n\r\n"
#define REQ_HEAD_BOUNDARY_LAST "----------------------------693106696888796587382791--\r\n"

    char *send_dat = "opt=02&sn=4428A30032A0&token=AEFE1085F4A07E5C186185D08D6EDD0E2DC1FE9E2B0A3E0CCD8FB9A4383842E7&data=F2FEBBFC870E5AD3203C75A1996A1D1142FF8D838078B7BCF0F44D943A317E3C22642CCAF3185DC5&sign=cb3bc8defda5ee1242926f67f0929f75\r\n";
    char head_line_content_len[256] = {0};
    char send_buf[2048] = {0};
    char content_buf[2048] = {0};

    my_log("%s %d start.\n", __FUNCTION__, __LINE__); 

    /*content buf*/
    strcat(content_buf, REQ_HEAD_BOUNDARY);
    strcat(content_buf, REQ_HEAD_CONT_DISPOSIT_FILE);
    strcat(content_buf, REQ_HEAD_BOUNDARY);
    strcat(content_buf, REQ_HEAD_CONT_DISPOSIT_TEXT);
    strcat(content_buf, REQ_DAT_CONT_TYPE);
    strcat(content_buf, send_dat);
    strcat(content_buf, REQ_HEAD_BOUNDARY_LAST);

    my_log("%s %d content:[%d]%s.\n", __FUNCTION__, __LINE__, (int)strlen(content_buf),  content_buf); 
    snprintf(head_line_content_len, sizeof(head_line_content_len), "Content-Length: %d\r\n\r\n", (int)strlen(content_buf));

    /*build send buf*/
    strcat(send_buf, REQ_HEAD_POST);
    strcat(send_buf, REQ_HEAD_HOST);
    strcat(send_buf, REQ_HEAD_CLOSE);
    strcat(send_buf, REQ_HEAD_AGENT);
    strcat(send_buf, REQ_HEAD_CONT_TYPE);
    strcat(send_buf, head_line_content_len);
    strcat(send_buf, content_buf);


    my_log("%s %d send_buf:[%d]\n%s.\n", __FUNCTION__, __LINE__, (int)strlen(send_buf), send_buf); 

    print_hex((u8*)send_buf, strlen(send_buf));
    clt_tcp_send(send_buf);

    my_log("%s %d end.\n", __FUNCTION__, __LINE__); 

    return 0;
}

  

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值