zoukankan      html  css  js  c++  java
  • 关于tcp封装http协议

    如果tcp中没有上层协议,那么就是简单的数据包的传输,如果tcp中有上层协议,那么,当客户端把tcp包发给server的时候,server端的socket收到数据包后,从中分离出应用层协议,交给上层继续

    下面是一个tcp封装http的代码

    #include <netinet/in.h>
    /* For socket functions */
    #include <sys/socket.h>
    /* For gethostbyname */
    #include <netdb.h>
    
    #include <unistd.h>
    #include <string.h>
    #include <stdio.h>
    
    int main(int c, char **v)
    {
        const char query[] =
            "GET / HTTP/1.0
    "
            "Host: www.baidu.com
    "
            "
    ";
        
        //const char query[]="GET www.baidu.com/ HTTP/1.0
    ";
        const char hostname[] = "www.baidu.com";
        struct sockaddr_in sin;
        struct hostent *h;
        const char *cp;
        int fd;
        ssize_t n_written, remaining;
        char buf[1024];
    
        /* Look up the IP address for the hostname.   Watch out; this isn't
           threadsafe on most platforms. */
        h = gethostbyname(hostname);
        if (!h) {
            fprintf(stderr, "Couldn't lookup %s: %s", hostname, hstrerror(h_errno));
            return 1;
        }
        if (h->h_addrtype != AF_INET) {
            fprintf(stderr, "No ipv6 support, sorry.");
            return 1;
        }
    
        /* Allocate a new socket */
        fd = socket(AF_INET, SOCK_STREAM, 0);
        if (fd < 0) {
            perror("socket");
            return 1;
        }
    
        /* Connect to the remote host. */
        sin.sin_family = AF_INET;
        sin.sin_port = htons(80);
        sin.sin_addr = *(struct in_addr*)h->h_addr;
        if (connect(fd, (struct sockaddr*) &sin, sizeof(sin))) {
            perror("connect");
            close(fd);
            return 1;
        }
    
        /* Write the query. */
        /* XXX Can send succeed partially? */
        cp = query;
        remaining = strlen(query);
        while (remaining) {
          n_written = send(fd, cp, remaining, 0);
          if (n_written <= 0) {
            perror("send");
            return 1;
          }
          remaining -= n_written;
          cp += n_written;
        }
    
        /* Get an answer back. */
        while (1) {
            ssize_t result = recv(fd, buf, sizeof(buf), 0);
            if (result == 0) {
                break;
            } else if (result < 0) {
                perror("recv");
                close(fd);
                return 1;
            }
            fwrite(buf, 1, result, stdout);
        }
    
        close(fd);
        return 0;
    }

    其中注意query中字符串的用法,及相关http的请求的报文头。

  • 相关阅读:
    Python
    Java 内部类
    Django with uWSGI and nginx
    Android 使用AsyncTask 下载图片的例子,学会使用AsyncTask
    django QuerySet里那些常用又不常见的技巧
    android模拟器网络设置(局域网)
    iOS9 class dump header
    Qt之QHeaderView自定义排序(终极版)
    Qt之QHeaderView自定义排序(QSortFilterProxyModel)
    Qt之QHeaderView排序
  • 原文地址:https://www.cnblogs.com/cdwodm/p/4391850.html
Copyright © 2011-2022 走看看