网络基础(二)

应用层(重要写代码)

 

协议:是双方的一种约定

 

 

报头:

HTTP协议(超文本传输协议)

 

URL:通俗来说网址

 

 

urlencode:特殊字符的编码

urldecode:编码之后的解码

 

 

http抓包

 

 

http常见Header:

  1. Cookie:保存身份标识,避免重复登录,存字符串,保存数据有限(4K)

  2. POST:有Body

  3. GET:没Body

  4. referer:当前页面是从哪个页面跳转过来的,通过升级成https来解决修改referer问题

  5. location:告诉接下来要去哪个页面,搭配3XX使用

  6. Set_Cookie:保存身份信息,下次访问此网络是就不需要在登录

 

http状态码(响应结果如何):

  1. 2开头:成功

  2. 3开头:重定向(302重定向到其他页面)

  3. 4开头:客户端异常(例404,418(彩蛋))

  4. 5开头:服务器异常(504(网关超时))

 

http请求(客户端发给服务器)

  1. 首行:方法+url+http版本号

  2. Header:请求属性 冒号空格键值对

  3. 由空行结束

  4. Body:空行后面的都是Body

 

 

http响应(服务器回发给客户端)

  1. 首行:http版本号 +状态码  +对状态码的含义补充    

  2. Header:键值对

  3. 空行表示Header结束

  4. Body:空行后面都是Body

 

 

写一个最简易版本的http服务器

//不管什么请求,响应都是hello world

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <netinet/in.h>

#include <string.h>







//其实可以使用C++多态来解决类似问题

typedef struct sockaddr sockaddr;//通用形式

typedef struct sockaddr_in sockaddr_in;//保存真正的IP地址和端口号



int ServerInit(const char *ip,short port)

{

  int fd = socket(AF_INET,SOCK_STREAM,0);

  if(fd < 0)

  {

    perror("socket!\n");

    return -1;

  }



  sockaddr_in addr;

  addr.sin_family = AF_INET;

  addr.sin_addr.s_addr = inet_addr(ip);

  addr.sin_port = htons(port);

  socklen_t len = sizeof(addr);



  int ret = bind(fd,(sockaddr *)&addr,len);

  if(ret < 0)

  {

    perror("bind!\n");

    return -1;

  }



  ret = listen(fd,5);

  if(ret < 0)

  {

    perror("listen!\n");

    return -1;

  }

  return fd;

}

void *ThreadEntry(void *arg)

{

  int64_t new_fd = (int64_t)arg;

  while(1)

  {

    char buf[1024 * 10] = {0};

    read(new_fd,buf,sizeof(buf)-1);



    printf("[request] %s\n",buf);

    //构造http的响应

    //首行

    //字符串拼出来啥样页面就是啥样

    const char* first_line = "HTTP/1.1 302 Found\n";

    const char* blank_line = "\n";

    //const char* body = "<html>sabi</html>";

    char header[1024 *10] = {0};

    //sprintf(header,"Content-Type:text/html;\nContent-Length:%lu\n",strlen(body));

    sprintf(header,"Location:http://ww.baidu.com\n");//将会跳转到百度页面

    

    write(new_fd,first_line,strlen(first_line));

    write(new_fd,header,strlen(header));

    write(new_fd,blank_line,strlen(blank_line));

    //write(new_fd,body,strlen(body));

    return NULL;

  }

}

int main(int argc,char *argv[])

{

  if(argc != 3)

  {

    printf("Usage ./http_server [ip] [port]\n");

    return 1;

  }



  int listen_sork = ServerInit(argv[1],atoi(argv[2]));

  if(listen_sork < 0)

  {

    printf("ServerInit error!\n");

    return 1;

  }

  printf("ServerInit OK!\n");



  //多线程版本



  

  while(1)

  {

    sockaddr_in peer;

    socklen_t len = sizeof(peer);

    int64_t  new_fd = accept(listen_sork,(sockaddr *)&peer,&len);

    if(new_fd < 0)

    {

      perror("accept!\n");

      continue;

    }



    pthread_t tid;

    pthread_create(&tid,NULL,ThreadEntry,(void *)new_fd);



    pthread_detach(tid);

    

  }

  return 0;

}

 

应用层协议:HTTP,HTTPS,FTP,SSH......,还有自定制的协议,序列化与反序列化

 

 

传输层(问题调试)

 

端口号

端口号范围划分

  1. 0-1023:知名端口号,一些知名的应用层协议http,ftp等都有固定的端口号

  2. 1024-65535:操作系统动态分配的端口号

 

知名的端口号

  1. ssh:22

  2. ftp:21

  3. http:80

 

 

一个进程可以绑定多个端口号,创建多个进程就可以同时绑定多个端口号了

一个端口号不能被多个进程绑定

 

 

 

 

(易考)查看进程的PID

  1. ps aux | grep 进程名:查看进程的PID

  2. pidof 进程名

 

(易考)给一个端口号查看绑定的进程:

  1. netstat -anp | grep 端口号

 

UDP协议

UDP协议端格式

教科书格式

 

通用格式

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值