自己动手学TCP/IP–http协议(http报文头)
在前面的一篇文章中,简单了介绍了HTTP报文格式,详情参考http://www.firefoxbug.net/?cat=47。
这里大概介绍下基本的,常见的HTTP包头格式。
POST /report/getComment.jsp HTTP/1.1
Host: yeeg.com
Connection: keep-alive
Content-Length: 161
Origin: http://www.1g1g.com
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.77 Safari/535.7
content-type: application/x-www-form-urlencoded
Accept: */*
Referer: http://www.1g1g.com/player/loader.swf?uid=0.8106261373031884
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: JSESSIONID=C3F105F72E3602D6292D3E4561E8E400
上面是一个POST包的包头,其中Content-Length字段里面的值就是POST包数据段的长度。可以用
wireshark抓取POST包,会发现,post包是把报文头和数据内容分开来发的,会被TCP分片,然后重组。
具体这里不详细讨论。
GET /enclosure/2010-09-10T02_51_05-07_00.mp3 HTTP/1.1
Host: 805665086.podomatic.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.77 Safari/535.7
Accept: */*
Referer: http://www.1g1g.com/player/loader.swf?uid=0.8106261373031884
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
上面是一个GET包,GET包请求的资源都是在URL里面的,所以数据段也就没有了,可以通过抓包分析。
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 09:12:52 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Thu, 23 Dec 2010 19:29:26 GMT
ETag: "960fcf-4a6459-49818e3486374"
Accept-Ranges: bytes
Content-Length: 487
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: audio/mpeg
上面是一个http响应包,Content-Length指明了数据段的大小。
下面是我今天用C写了解析HTTP报文头的程序。注意:下面代码只主要用libcap实现实现了部分功能,具体
是解析GET包头,POST包头,还有HTTP相应包头,可能存在一些不足,希望大家多多交流。
- /*
- capture http packet by firefoxbug
- */
- #include <pcap.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <net/ethernet.h>
- #include <netinet/ip_icmp.h> //Provides declarations for icmp header
- #include <netinet/udp.h> //Provides declarations for udp header
- #include <netinet/tcp.h> //Provides declarations for tcp header
- #include <netinet/ip.h> //Provides declarations for ip header
- #define BUFFSIZE 1500
- typedef struct port{
- unsigned int src_port;
- unsigned int des_port;
- }Port;
- Port port;
- int tcp=0;
- FILE *logfile;
- int size;
- void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer);
- char *print_tcp_packet(const char *Buffer);
- void get_line(char *data,char *buff,int length);
- void print_http_req_packet(char *data);
- void print_http_ans_packet(char *data);
- int main(int argc,char *argv[])
- {
- pcap_if_t *alldevsp , *device;
- pcap_t *handle; //Handle of the device that shall be sniffed
- char errbuf[100] , *devname , devs[100][100];
- int count = 1 , n;
- //First get the list of available devices
- printf("Finding available devices ... ");
- if( pcap_findalldevs( &alldevsp , errbuf) )
- {
- printf("Error finding devices : %s" , errbuf);
- exit(1);
- }
- printf("Done");
- //Print the available devices
- printf("\nAvailable Devices are :\n");
- for(device = alldevsp ; device != NULL ; device = device->next)
- {
- printf("%d. %s - %s\n" , count , device->name , device->description);
- if(device->name != NULL)
- {
- strcpy(devs[count] , device->name);
- }
- count++;
- }
- //Ask user which device to sniff
- printf("Enter the number of the device you want to sniff : ");
- scanf("%d" , &n);
- devname = devs[n];
- //Open the device for sniffing
- printf("Opening device %s for sniffing ... " , devname);
- handle = pcap_open_live(devname , 65536 , 1 , 0 , errbuf);
- if (handle == NULL)
- {
- fprintf(stderr, "Couldn't open device %s : %s\n" , devname , errbuf);
- exit(1);
- }
- printf("Done\n");
- logfile=fopen("log.txt","w");
- if(logfile==NULL)
- {
- printf("Unable to create file.");
- }
- //Put the device in sniff loop
- pcap_loop(handle , -1 , process_packet , NULL);
- return 0;
- }
- void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer)
- {
- size = header->len;
- // fprintf(logfile,"length of packet : %d \n",size);
- //Get the IP Header part of this packet , excluding the ethernet header
- struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));
- switch (iph->protocol) //Check the Protocol and do accordingly...
- {
- case 6: //TCP Protocol
- ++tcp;
- // printf("TCP : %d \n", tcp);
- unsigned char *data = print_tcp_packet(buffer);
- if (size <= 0)
- break;
- if (port.des_port == 80)
- {
- print_http_req_packet(data);
- }
- else if ( port.src_port == 80 )
- {
- print_http_ans_packet(data);
- }
- break;
- }
- }
- char *print_tcp_packet(const char *Buffer)
- {
- //IP header
- struct iphdr *iph = (struct iphdr *)( Buffer + sizeof(struct ethhdr) );
- unsigned int iphdrlen = iph->ihl*4;
- //TCP header
- struct tcphdr *tcph=(struct tcphdr*)(Buffer + iphdrlen + sizeof(struct ethhdr));
- port.src_port = ntohs(tcph->source);
- port.des_port = ntohs(tcph->dest);
- // mac_header + ip_header + tcp_header
- int header_size = sizeof(struct ethhdr) + iphdrlen + tcph->doff*4;
- size = size - header_size;
- // fprintf(logfile,"length of header : %d \n",header_size );
- return (char *)(Buffer + header_size);
- }
- void print_http_req_packet(char *data)
- {
- if( strncmp(data,"GET",3) == 0 || strncmp(data,"POST",4) == 0 )
- {
- fprintf(logfile,"\n/***********************length of data : %d**********************/ \n",size);
- fprintf(logfile,"From %d To %d \n",port.src_port,port.des_port);
- int i = 0;
- for( ; i < size ; ++i)
- {
- fprintf(logfile,"%c",*(data + i));
- }
- fprintf(logfile,"/***************************** end *******************************/ \n\n");
- }
- return ;
- }
- void print_http_ans_packet(char *data)
- {
- if( strncmp(data,"HTTP",4) == 0 )
- {
- fprintf(logfile,"\n/***********************length of data : %d**********************/ \n",size);
- fprintf(logfile,"From %d To %d \n",port.src_port,port.des_port);
- char buff[BUFFSIZE] = {'\0'};
- get_line(data,buff,size);
- fprintf(logfile,"%s",buff);
- unsigned int off = strlen(buff);
- size = size - off;
- while(strcmp(buff,"\r\n") != 0)
- {
- memset(buff,'\0',sizeof(buff));
- get_line(data + off,buff,size);
- fprintf(logfile,"%s",buff);
- off = off + strlen(buff);
- size = size - off;
- }
- fprintf(logfile,"/***************************** end *******************************/ \n\n");
- }
- }
- void get_line(char *data,char *buff,int length)
- {
- int i = 0;
- char ch;
- for ( ; i < length;++i)
- {
- ch = *(data + i);
- *(buff + i) = ch;
- if(ch == '\n')
- break;
- }
- }
自己动手学TCP/IP–http协议(http报文头)的更多相关文章
- 跟我学TCP/IP系列
最近在微信公众号“java与Android开发专栏”,看到系列文章“跟我学TCP/IP系列”,共7章,文章很赞. 系列文章在CSDN上也有分发,下列出地址以备以后查看(版权问题不转载内容). http ...
- 对TCP/IP网络协议的深入浅出归纳
前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网 ...
- 转:对TCP/IP网络协议的深入浅出归纳
转自:http://blog.jobbole.com/74795/ 前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没 ...
- 对TCP/IP网络协议的深入浅出归纳(转)
前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网 ...
- TCP/IP网络协议的通俗理解,SOCKET,HTTP,SOAP
TCP/IP,HTTP,SOAP等协议之区别 术语TCP/IP代表传输控制协议/网际协议,指的是一系列协议.“IP”代表网际协议,TCP和UDP使用该协议从一个网络传送数据包到另一个网络.把IP想 ...
- Linux学习(1)- TCP/IP网络协议基础
Linux学习(1)- TCP/IP网络协议基础 一.TCP/IP 简介 学习内容 TCP/IP(Transmission Control Protocol/Internet Protocol)是传输 ...
- 计算机网络【1】—— OSI七层协议和TCP/IP四层协议
新开一贴,专门用来记录计算机网络相关知识. 一.OSI七层协议 物理层.数据链路层.网络层.传输层.会话层.表示层.应用层 二.TCP/IP四层协议 网络接口层.网际层.运输层.应用层 三.五层协议 ...
- TCP/IP四层协议模型与ISO七层模型
TCP/IP四层协议模型与ISO七层模型 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他 ...
- TCP/IP网络协议基础
实验楼学习网络协议传送门 一.TCP/IP简介 TCP/IP(Transmission Control Protocol/Internet Protocol)是传输控制协议和网络协议的简称,它定义了电 ...
随机推荐
- [HTML5] Emmet
For example we want to generate the code like this: <a href="#tab1">Tab 1</a>& ...
- 从零開始开发Android版2048 (五) 撤销的实现
本篇的内容是,在前一篇的基础上添�了撤销的功能.撤销事实上就是将当前的用户界面恢复到这次滑动值前的样子.我实现撤销的主要原理是,将每次滑动后界面上的格子和相应的数字记录下来,当然还有分数,把这些数据写 ...
- 通过扩展RandomAccessFile类使之具备Buffer改善I/O性能--转载
主体: 目前最流行的J2SDK版本是1.3系列.使用该版本的开发人员需文件随机存取,就得使用RandomAccessFile类.其I/O性能较之其它常用开发语言的同类性能差距甚远,严重影响程序的运行效 ...
- 从C到汇编:栈是计算机工作的基础
作者:r1ce 原创作品转载请注明出处 <Linux内核分析> MOOC课程http://mooc.study.163.com/course/U ...
- NYOJ128前缀式计算
前缀式计算 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 先说明一下什么是中缀式: 如2+(3+4)*5这种我们最常见的式子就是中缀式. 而把中缀式按运算顺序加上括 ...
- Wpf TextChanged事件导致死循环,事件触发循环问题
1.实例: 说明:当TextBox控件的Text内容发生变化时,TextChanged事件触发,并且会立即同步执行. 基于这个特点,设置一个全局变量标识,ChangeTxtB,如果是正在修改txtB的 ...
- (转)JS的parent对象
---http://blog.sina.com.cn/s/blog_a15aa5690101a5yz.html top:该变更永远指分割窗口最高层次的浏览器窗口.如果计划从分割窗口的最高层次开始执行命 ...
- 用ASP.net判断上传文件类型的三种方法
一. 安全性比较低,把文本文件1.txt改成1.jpg照样可以上传,但其实现方法容易理解,实现也简单,所以网上很多还是采取这种方法. Boolean fileOk = false; ...
- Android开发手记(19) 数据存储四 ContentProvider
转载自:http://www.cnblogs.com/devinzhang/archive/2012/01/20/2327863.html Android为数据存储提供了五种方式: 1.SharedP ...
- iOS9中将图片保存到照片中的某个相册的方法说明
iOS9中将图片保存到照片中的某个相册的方法说明 在App中很经常遇到的就是用户点击某张图片后将图片保存到本地,下面介绍下iOS中保存图片的一些东西 1.首先,在iOS中把图片保存到系统照片是比较简单 ...