TCP/IP模型之应用层及HTTP协议

应用层的功能

负责应用程序间的沟通来制定协议,通俗的来讲就是应用层会借助TCP、UDP协议在各种各样的程序之间传递数据(邮件、文件等等),这时候像应用层协议就可以规定这些数据的格式要满足什么样。

常见应用层协议:(带*要熟知)

–基于TCP的应用层协议 –基于UDP的应用层协议
*简单电子邮件传输协议(SMTP) *动态主机配置协议(DHCP)
*文件传输协议(FTP) *域名解析协议(DNS)
*网络远程访问协议(Telnet) 网络文件系统(NFS)、简单文件传输协议(TFTP)启动协议(BOOTP)
*超文本传输协议(HTTP)

认识HTTP协议

1、http请求:

  • 首行:方法+url+版本号
  • Header:表示请求的属性,是一个个键值对(键:值),每个键值对用\n隔开,遇到空行Header就结束了。
  • Body:空行后面的内容,如果存在Body首先方法应该是POST方法,而且对应Header中会有一个字段Content-Length,这个字段表示Body的长度

TCP/IP模型之应用层及HTTP协议_第1张图片

2、http响应

  1. 首行:版本号+状态码+状态码解释

这里说到了状态码,那就讲一下:

状态码 类别 原因
1xx 信息性状态码 接受的请求正在处理
2xx 成功状态码 请求正常处理完毕
3xx 重定向状态码 需要进行附加操作以完成请求
4xx 客户端错误状态码 服务器无法处理请求
5xx 服务器错误状态码 服务器处理请求错误

常见的错误码:200(表示请求正常处理OK) 404(NOT FOUND)403(Forbidden) 302(Redirect) 504(Bad Gateway不可用) 502(超时)

  1. Header:请求的属性,也是键值对,键值对之间用\n分隔,遇到空行表示Header结束。
  2. Body:空行后面的内容就是Body部分,如果存在Body对应Header中会有一个字段Content-Length,这个字段表示Body的长度,如果服务器返回一个html页面,那么页面内容就在body中。

3、常见的HTTP方法

方法 功能 支持的协议版本
GET 获取资源(表示从服务器上获取) 1.0、1.1
POST 传输实体主体 1.0、1.1
PUT 传输文件 1.0、1.1

GET方法和POST方法最大的区别在于GET方法没有Body部分,所以Header中就没有Content-Length和Content-Type这两个键值对。

4、HTTP常见Header

  1. Content-Type:数据类型(text/html等)
  2. Content-Length:Body的长度
  3. Host:客户端告知服务器,所请求的资源在那个主机的哪个端口上。
  4. User-Agent:声明用户的操作系统和浏览器版本信息
  5. Cookie:用于在客户端存储少量信息,(比如说访问需要用户登录的界面),通常用于实现会话的功能。

5、简单版本的Http服务器

此服务器中构造了响应,打印“hello world”,

#include
#include
#include
#include
#include
#include
#include
typedef struct sockaddr_in sockaddr_in;
typedef struct sockaddr sockaddr;
int main(int argc,char* argv[]){
    if(argc!=3){
        perror("Usage [ip][port]\n");
        return 1;
    }
    int sock=socket(AF_INET,SOCK_STREAM,0);
    if(sock<0){
        perror("sock\n");
        return 2;
    }
    sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_addr.s_addr=inet_addr(argv[1]);
    local.sin_port=htons(atoi(argv[2]));
    int ret=bind(sock,(sockaddr*)&local,sizeof(local));
    if(ret<0){
        printf("bing fail\n");
        return 3;
    }
    ret=listen(sock,5);
    if(ret<0){
        perror("listen\n");
 return 3;
    }
    //while
    while(1){
        sockaddr_in peer;
        socklen_t len=sizeof(peer);
        int new_sock=accept(sock,(sockaddr*)&peer,&len);
        if(new_sock<0){
            perror("accept\n");
            continue;
        }
        char in_buf[1024*10]={0};
        ssize_t read_size=read(new_sock,in_buf,sizeof(in_buf)-1);
        if(read_size<0){
            perror("read\n");
            return 1;
        }
        else if(read_size==0){
            close(new_sock);
        }
        in_buf[read_size]=0;
printf("client say:%s\n",in_buf);
        char out_buf[1024]={0};
        const char* hello="

hello world

"
; sprintf(out_buf,"HTTP/1.0 200 OK\nContent-Length:%lu\n\n%s",strlen(hello),hello);//此处是将参数二作为构造的HTTP响应,格式化的写进new_sock中 write(new_sock,out_buf,strlen(out_buf)); } }

你可能感兴趣的:(Linux部分,网络)