2010-07-25 09:17:00 vanwaals 阅读数 938
  • Linux程序设计从入门到实战

    C/C++属于系统级别的编程语言,作为开源软件的代表作品Linux操作系统是所有C/C++程序员都应当熟悉和掌握的。本门课程从实战出发,降低了初级 C/C++程序员进入Linux程序设计的门槛。本门课程以Centos为实验环境,从核心命令讲解,再到gcc/gdb开发环境,直至覆盖到460多个常用的类Unix/POSIX API。本课可以有效的节约初学者上手Linxu操作系统的时间。同时,课程结合GNU的开源代码,仿真实现Linux常用命令,展现类Unix系统调用的工程级别的实现思路,重点讲解Linux环境下的开发和接口函数,多线程并发 ,并最终实现了一个带有CGI功能的小型http服务器。本课程结合计算机程序运行原理等内容,增加学员实际编程代码量,提升实战能力。

    1212 人正在学习 去看看 夏曹俊

在网上下载了 PrefixSpan 的C++ linux实现

http://chasen.org/~taku/software/prefixspan/

是日本人写的

 

在windows 和 linux下都编译不通过。

分析原因:

 

linux下:

 见上一篇文章,是因为 C++ 模板类 map::iterator 不能区分是否是类型,

加上 typename 后编译 运行 成功。

 

windows下:

去掉 linux头文件

加入,getopt 的 windows 实现版本

编译通过运行出错,如《http://blog.csdn.net/vasco/archive/2007/04/10/1558656.aspx

原程序中是pattern.erase (pattern.end()),老是提示超出边界,所以我改成pattern.pop_back()

 

改为 pattern.pop_back() 后运行成功。

分析原因,因为 pattern.end() 返回的是 最后一个元素的下一个位置。改为 pattern.erase (pattern.end()-1) 后运行成功

 

不知道 为什么 没有减一却可以在 linux下正常运行?

2017-12-08 23:09:31 qq_36359022 阅读数 2012
  • Linux程序设计从入门到实战

    C/C++属于系统级别的编程语言,作为开源软件的代表作品Linux操作系统是所有C/C++程序员都应当熟悉和掌握的。本门课程从实战出发,降低了初级 C/C++程序员进入Linux程序设计的门槛。本门课程以Centos为实验环境,从核心命令讲解,再到gcc/gdb开发环境,直至覆盖到460多个常用的类Unix/POSIX API。本课可以有效的节约初学者上手Linxu操作系统的时间。同时,课程结合GNU的开源代码,仿真实现Linux常用命令,展现类Unix系统调用的工程级别的实现思路,重点讲解Linux环境下的开发和接口函数,多线程并发 ,并最终实现了一个带有CGI功能的小型http服务器。本课程结合计算机程序运行原理等内容,增加学员实际编程代码量,提升实战能力。

    1212 人正在学习 去看看 夏曹俊

备注:该文件服务器是根据Tinyhttpd的http源码的基础上实现的

整体思路: 创建socket监听请求,收到请求后线程分离,在线程中进行请求数据的解析;根据解析到的消息我们分类处理,目前该文件服务器可提供的文件包括html、css、jpg、gif;

1.监听请求,; 首先设置了端口复用,这个从字面理解就好了,就是说该端口上可以绑定多个socket;分配套接字,Http文件服务器是基于TCP传输协议; 初始化监听的地址结构体; 套接字与地址结构体绑定;

  /*端口复用*/
  int opt = 1;
  setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
  /*分配一个TCP套接字*/
  server_fd = Socket(AF_INET, SOCK_STREAM, 0);     //TCP
  /*初始化*/
  bzero(&server_addr, server_addr_len);            //清空
  server_addr.sin_family      = AF_INET;
  server_addr.sin_port        = htons(SERVER_PORT);
  server_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
  /*绑定*/
  bind(server_fd, (struct sockaddr*)&server_addr, server_addr_len);
  listen(server_fd, 128); //最多可支持128个请求连接同时在服务器 监听套接字 上等待处理                                          
  printf("httpServer running on port %d \n", SERVER_PORT);

2.循环监听,这里的accept函数是从步骤1中的listen函数的等待请求队列里接受一个连接; 自定义结构体,打包了文件描述符,地址,地址大小; 创建线程并分离,所有的处理工作在do_work函数中;

/*  自定义结构体
    struct t_client_info{
       int                 t_fd;
       struct sockaddr_in  t_addr;
       socklen_t           t_addr_len;
    };
*/
while(1)
  {
    client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_addr_len);
    t_info.t_fd       = client_fd;                 //该部分是我自定义的结构体
    t_info.t_addr     = client_addr;               //用于打包客户端套接字信息
    t_info.t_addr_len = client_addr_len;           //方便传递到下个线程
    /*线程*/
    pthread_create(&t_client, NULL, do_work, (void *)&t_info); //创建线程
    pthread_detach(t_client);  
  }

3.do_work()函数

3.1 初始化

 /*初始化*/
  Pt_this = (struct t_client_info *)arg;   //从父线程上传递来的自定义结构体
  int                 client_fd        = Pt_this->t_fd;
  struct sockaddr_in  client__addr     = Pt_this->t_addr;
  socklen_t           client_addr_len  = Pt_this->t_addr_len;

3.2 进入函数后不要盲目的直接调用开始处理请求行,我们先判断这个客户端的下一步动作,
如果recv返回了但是num为0,说明客户端套接字主动断开连接,这里直接goto到线程
收尾工作;

//判断缓冲区是否有东西可读,用MSG_PEEK,不会移动滑动窗口
  int num=0;
  char c;
  num = recv(client_fd, &c, 1, MSG_PEEK);
  if (num != 1)
     goto workEND;

3.3 处理请求头的第一行数据,一般格式是 (方法 文件路径 协议版本)
例如:GET /index.html HTTP/1.1
注意: #define ISsp(x) isspace((int)(x)) //用于判断空格;
get_line()函数 获取一行数据,自定义函数,以 \r\n判断;

/*接收请求行的数据*/
  numchars = get_line(client_fd, buf, sizeof(buf));
  i=0; j=0;

  //获取方法字段
   while (!ISsp(buf[i]) && (i<sizeof(method)-1))  //留一格用在‘\0’
   {
     method[i] = buf[i];
      i++;
   }
   j = i; //记录当前空格的位置
   i = 0;
   method[i] = '\0';
 //判断方法
   if (strcasecmp(method, "GET")
     && strcasecmp(method, "POST")) //忽略大小写比较字符串,相同返回0;
                                    //这里是除了get和post以外都返回
      goto workEND;

    //如果请求方法是POST,我们用调用cgi程序,cgi==1 调用cgi cgi==0 提供静态文件
   if (strcasecmp(method, "POST") == 0)  //POST
       cgi = 1;

3.4 获取URL,即获取客户端想要请求的文件路径;

 //j当前的位置是method后面的空格 
    while (ISsp(buf[j]) && (j<numchars)) 
          j++;
    //获取URL
    while (!ISsp(buf[j]) && (i<sizeof(url)-1) && (j<numchars))
    {
       url[i] = buf[j];
       i++; j++;
    }
    url[i] = '\0';

3.5 客户端请求的URL一般是请求的Http文件服务器的站点目录
如果请求的是 /index.html ===> 那么在我的设置里对应的 是/root/Project/WebFileServer/File/index.html
一定要区分客户端请求的根目录其实是服务器上的站点根目录

/*保存有效的url并加上默认主页索引, 默认在 */
    /*
      #define ROOT /root/Project/WebFileServer/File%s
    */ 
    sprintf(path, ROOT, url);
    //最后结尾是‘/’代表请求的是一个目录文件服务器应该返回该目录中的index.html
    if (path[strlen(path)-1] == '/')       
       strcat(path, "index.html");

//获取了URL后,再获取该URL的文件信息,如果获取失败,那就结束这次响应
/*通过文件名path获取文件信息,并保存在st所指向的结构体stat中*/
    if (stat(path, &st) == -1)   //获取失败,丢弃剩下的数据
    {
       while ((numchars>0) && strcmp("\n", buf))  //不是\n返回1
          numchars = get_line(client_fd, buf, sizeof(buf));
        /*
           这里可以返回404页面
        */ 
       goto workEND;
    }

    if ((st.st_mode & S_IFMT) == S_IFDIR) //目录类型
       strcat(path, "/index.html");

       /*检查文件路径是否存在*/
       int exist = access(path, F_OK);
       if (exist == -1) //不存在

3.6 返回文件根据cgi的值,cgi等于1代表是POST,我们提交到cgi程序处理;
cgi等于0代表是普通的GET,文件服务器直接返回静态文件;


/*返回文件*/
       if (!cgi)  //返回静态文件
           server_file(client_fd, path);    //自定义函数,返回静态文件
       else
       {
           /*
              这里实现调用cgi程序
           */
       }

workEND:
    close(client_fd);

4.get_line()函数 : 该函数为Tinyhttpd源码,可以放心的使用

int get_line(int sock, char *buf, int size)
{
  printf("##get_line## \n");          // 1.字符   2.字符\r    3.字符\r\n
  int i = 0;  
    char c = '\0';  
    int n;  

    /*把终止条件统一为 \n 换行符,标准化 buf 数组*/  
    while ((i < size - 1) && (c != '\n'))  
    {  
        /*一次仅接收一个字节*/  
        n = recv(sock, &c, 1, 0);   
        if (n > 0)  
        {  
            /*收到 \r 则继续接收下个字节,因为换行符可能是 \r\n */  
            if (c == '\r')  
            {  
                /*使用 MSG_PEEK 标志使下一次读取依然可以得到这次读取的内容,可认为接收窗口不滑动*/  
                n = recv(sock, &c, 1, MSG_PEEK);    
                /*但如果是换行符则把它吸收掉*/  
                if ((n > 0) && (c == '\n'))  
                    recv(sock, &c, 1, 0);  
                else  
                    c = '\n';  
            }  
            /*存到缓冲区*/  
            buf[i] = c;  
            i++;  
        }  
        else  
            c = '\n';  
    }  
    buf[i] = '\0';  

    /*返回 buf 数组大小*/  
    return(i);
} 

5.提供静态文件(其中包括html、css、jpg、gif、下载文件)

void server_file(int fd, const char *filename)
{
  printf("##server_file## \n");

  char *string = NULL;

  string = &filename[strlen(filename)-4];
  else if (strcasecmp(string, ".jpg") == 0)
     pic(fd, filename);

  else if (strcasecmp(string, ".gif") == 0)
     gif(fd, filename);

  else if (strcasecmp(string, ".css") == 0)
     css(fd, filename);

  string = &filename[strlen(filename)-5];
  if (strcasecmp(string, ".html") == 0)
     html(fd, filename);

  /*如果不是,则下载*/
   Download(fd, filename);
}

6.这里给出只给出提供html文件的函数和下载文件函数;其他函数实现类似

/*
    返回html,注意按照Http协议格式
      |    |    |    |    |    |    |    |    |    |    |    |
      v    v    v    v    v    v    v    v    v    v    v    v
*/
void html(int fd, const char *filename)
{
  FILE *resource = NULL;
  int numchars = 1;
  char buf[BUFSIZ];

  buf[0] = 'A'; buf[1] = '\0';
  while ((numchars > 0) && strcmp("\n", buf))      /*这里要读完请求头的所有数据*/
      numchars = get_line(fd, buf, sizeof(buf));
  resource = fopen(filename, "r");
  if (resource == NULL)
  {
    fclose(resource);
    return ;
  }
  else
  {
       //注意:可以使用filename的信息来返回文件类型
        strcpy(buf, "HTTP/1.1 200 OK\r\n");
        send(fd, buf, strlen(buf), 0);
        strcpy(buf, SERVER_STRING);
        send(fd, buf, strlen(buf), 0);
        sprintf(buf, "Content-Type: text/html\r\n");
        send(fd, buf, strlen(buf), 0);
        strcpy(buf, "\r\n");
        send(fd, buf, strlen(buf), 0);

        fgets(buf, sizeof(buf), resource);
        while (!feof(resource))   //其功能是检测流上的文件结束符,如果文件结束,则返回非0值,否则返>回 0,文件结束符只能被clearerr()清除
        {
            send(fd, buf, strlen(buf), 0);
            fgets(buf, sizeof(buf), resource);
        }                               
  }
  fclose(resource);
}

下载文件需要注意的是返回类型,在html返回中服务器的发送的响应头里,Content-Type设置的是text/html;在下载类型中需要采用application/octet-stream,此为下载类型,用二进制传输文件;
注意:该下载文件实现是用的大文件分块传输,切记发送数据时要保证文件要关闭,不要在打开文件的状态传输数据,当客户端关闭时服务器会退出;

void Download(int fd, const char *filename)
{
  printf("##Download## fd:%d \n", fd);

  FILE *resource = NULL;
  char *p = NULL;
  int numchars = 1;
  char buf[BUFSIZ];
  long file_len=0;

  buf[0] = 'A'; buf[1] = '\0';                 //拿出所有的请求消息
  while ((numchars > 0) && strcmp("\n", buf)) 
     numchars = get_line(fd, buf, sizeof(buf));

  resource = fopen(filename, "r");
  if (resource == NULL)
  {
     printf("file  not found \n");
     fclose(resource);
     return ;
  }
     fseek(resource, 0, SEEK_END); //一直到文件尾
     file_len = ftell(resource);    //长度
     //rewind(resource);             //将文件指针指向开头
     fclose(resource);

     //注意:可以使用filename的信息来返回文件类型
     strcpy(buf, "HTTP/1.1 200 OK\r\n");
     send(fd, buf, strlen(buf), 0);
     strcpy(buf, SERVER_STRING);          //自定义宏,服务器信息
     send(fd, buf, strlen(buf), 0);   
    sprintf(buf, "Connection: keep-alive\r\nContent-type:application/octet-stream\r\n");
     send(fd, buf, strlen(buf), 0);
     sprintf(buf, "Content-Length: %ld\r\n\r\n", file_len);
     send(fd, buf, strlen(buf), 0);

     //在\r\n\r\n后面就该放数据了,这里采用大文件分块
     //写入文件内容
      long seek=0;
      long wait_len = file_len - seek;
      long send_len=0;
      double mb=0;

      if (wait_len > FILELEN)   //自定义宏,暂时设为1MB    
        send_len = FILELEN;
      else
        send_len = wait_len;
     /*动态分配空间,在这里没有做错误处理*/
      p = (char *)malloc(sizeof(char)*send_len);
      int sendnum=0; 

      while(1)
      {
        resource = fopen(filename, "r");
        if (resource == NULL)
        {
          printf("file open false\n");
          fclose(resource);
          return ;
        }
        if (!fread(p, sizeof(unsigned char), send_len, resource))
break;
        fclose(resource);

        //(自定义函数,代码在下面)判断套接字是否断开
        //如果在对方断开时继续send,将会出现一些异常
        if (isConnection(fd) == -1)  //0连接 -1断开
           break;

        send(fd, p, send_len, 0);

        printf("sendnum:-%d-\n", sendnum);
        seek = seek + send_len;
        wait_len = file_len - seek;

        if (wait_len > FILELEN)       
          send_len = FILELEN;
        else
          send_len = wait_len;
        mb = (double)((double)seek/(double)1048576);
        printf("seek:-%ld-===>-%lfMB-\n", seek, mb);
      }
  }  

     free(p);
     p = NULL;
     printf("Download end.\n");

//自定义函数,判断连接是否断开
int isConnection(int fd)
{
   struct tcp_info info; 
   int len=sizeof(info); 
   getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len); 
   if((info.tcpi_state == TCP_ESTABLISHED))
      return 0;
   else
      return -1;
}

7.文件上传
首先是客户端,一般采用POST方法提交到文件服务器上的一个cgi程序,在步骤3.6中我们实现了提供静态文件,这里来描述如果利用cgi上传文件到服务器;
步骤为:客户端按下按键发送一个带有文件的POST请求 ==> 服务器接收请求并获取文件信息 ==> 服务器接收文件数据并存储

客户端的提交信息:
POST /CGI/down.cgi?filename=xxx HTTP/1.1\r\n
… …\r\n\r\n
(file data)

这里请求了根目录下CGI目录中的down.cgi这个程序,提交的文件名放在xxx这个位置,这部分是在客户端实现的;服务器收到请求调用down.cgi ; 该cgi可以用C写也可以用Shell,Python… … 本次采用的C语言实现cgi程序;

void execute_postFile(int fd, char *path, char *method, char *requestline)
{
    char file[] = "/root/Project/WebFileServer/File/CanUseFile/";  //这是我保存文件的路径
    char buf[BUFSIZ];
    int numchars = 1;
    int content_len = -1;

    buf[0]='A';buf[1]="\0";                //如果是GET我们不处理;拿出所有请求数据
    if (strcasecmp(method, "GET") == 0)
       while ((numchars>0) && strcmp("\n", buf))
          numchars = get_line(fd, buf, sizeof(buf));

    else if (strcasecmp(method, "POST") == 0)
    {
       /*请求头中我们需要Content-Length*/
       numchars = get_line(fd, buf, sizeof(buf));
       while ((numchars>0) && strcmp("\n", buf))
       {  
          buf[15] = '\0';
          if (strcasecmp(buf, "Content-Length:") == 0)
             content_len = atoi(&(buf[16]));
          numchars = get_line(fd, buf, sizeof(buf));
          printf("--%s-- \n", buf);
       }
       if (content_len == -1)
       {  
          printf("bad request \n");
          return ;
       }
    }
    else
    {
      //other method
    }

    /*获取requestline中的文件名,  ?filename=xxx*/
    char *post_string = requestline;
    char filename[BUFSIZ];
    int filenum = 0;
    while ((*post_string != '?') && (*post_string != '\0'))
       post_string++;
    if (*post_string == '?')
    {
      post_string = post_string + 10;
      while (!ISsp(*post_string))
      {
         filename[filenum] = *post_string;
         filenum++;
         post_string++;
      }
      filename[filenum] = '\0';
    }



    strcat(file, filename);
    printf("file:-%s-", file);
    FILE *fp = NULL;
    fp = fopen(file, "wb");   //以二进制写入,创建文件
    if (fp == NULL)
    {
       printf("file  not found \n");
       fclose(fp);
       return ;
    }

    int i;
    char c;
    for(i=0; i<content_len; i++)
    {
      recv(fd, &c, 1, 0);
      fwrite(&c, sizeof(unsigned char), 1, fp);
    }
    fclose(fp);
    /*
    这里可以向客户端返回保存信息
    */
   }

感谢你耐心的看完了这篇文章,希望能够帮助到你

2014-12-06 17:05:18 jsh13417 阅读数 26509
  • Linux程序设计从入门到实战

    C/C++属于系统级别的编程语言,作为开源软件的代表作品Linux操作系统是所有C/C++程序员都应当熟悉和掌握的。本门课程从实战出发,降低了初级 C/C++程序员进入Linux程序设计的门槛。本门课程以Centos为实验环境,从核心命令讲解,再到gcc/gdb开发环境,直至覆盖到460多个常用的类Unix/POSIX API。本课可以有效的节约初学者上手Linxu操作系统的时间。同时,课程结合GNU的开源代码,仿真实现Linux常用命令,展现类Unix系统调用的工程级别的实现思路,重点讲解Linux环境下的开发和接口函数,多线程并发 ,并最终实现了一个带有CGI功能的小型http服务器。本课程结合计算机程序运行原理等内容,增加学员实际编程代码量,提升实战能力。

    1212 人正在学习 去看看 夏曹俊

前段时间,帮朋友实现linux C实现HTTP get 及POst请求,最原先打算使用libcurl库实现。但是考虑到和其他接口通信的情况,暂时使用C 来实现.代码可以自动解析URL连接,具体看下面代码:

/*File : http.h
 *Auth : sjin
 *Date : 20141206
 *Mail : 413977243@qq.com
 */
#ifndef _MY_HTTP_H
#define _MY_HTTP_H

#define MY_HTTP_DEFAULT_PORT 80

char * http_get(const char *url);
char * http_post(const char *url,const char * post_str);

#endif

/*File : http.c
 *Auth : sjin
 *Date : 20141206
 *Mail : 413977243@qq.com
 */
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>

#include "http.h"

#define BUFFER_SIZE 1024
#define HTTP_POST "POST /%s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: */*\r\n"\
    "Content-Type:application/x-www-form-urlencoded\r\nContent-Length: %d\r\n\r\n%s"
#define HTTP_GET "GET /%s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: */*\r\n\r\n"


static int http_tcpclient_create(const char *host, int port){
    struct hostent *he;
    struct sockaddr_in server_addr; 
    int socket_fd;

    if((he = gethostbyname(host))==NULL){
        return -1;
    }

   server_addr.sin_family = AF_INET;
   server_addr.sin_port = htons(port);
   server_addr.sin_addr = *((struct in_addr *)he->h_addr);

    if((socket_fd = socket(AF_INET,SOCK_STREAM,0))==-1){
        return -1;
    }

    if(connect(socket_fd, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1){
        return -1;
    }

    return socket_fd;
}

static void http_tcpclient_close(int socket){
    close(socket);
}

static int http_parse_url(const char *url,char *host,char *file,int *port)
{
    char *ptr1,*ptr2;
    int len = 0;
    if(!url || !host || !file || !port){
        return -1;
    }

    ptr1 = (char *)url;

    if(!strncmp(ptr1,"http://",strlen("http://"))){
        ptr1 += strlen("http://");
    }else{
        return -1;
    }

    ptr2 = strchr(ptr1,'/');
    if(ptr2){
        len = strlen(ptr1) - strlen(ptr2);
        memcpy(host,ptr1,len);
        host[len] = '\0';
        if(*(ptr2 + 1)){
            memcpy(file,ptr2 + 1,strlen(ptr2) - 1 );
            file[strlen(ptr2) - 1] = '\0';
        }
    }else{
        memcpy(host,ptr1,strlen(ptr1));
        host[strlen(ptr1)] = '\0';
    }
    //get host and ip
    ptr1 = strchr(host,':');
    if(ptr1){
        *ptr1++ = '\0';
        *port = atoi(ptr1);
    }else{
        *port = MY_HTTP_DEFAULT_PORT;
    }

    return 0;
}


static int http_tcpclient_recv(int socket,char *lpbuff){
    int recvnum = 0;

    recvnum = recv(socket, lpbuff,BUFFER_SIZE*4,0);

    return recvnum;
}

static int http_tcpclient_send(int socket,char *buff,int size){
    int sent=0,tmpres=0;

    while(sent < size){
        tmpres = send(socket,buff+sent,size-sent,0);
        if(tmpres == -1){
            return -1;
        }
        sent += tmpres;
    }
    return sent;
}

static char *http_parse_result(const char*lpbuf)
{
    char *ptmp = NULL; 
    char *response = NULL;
    ptmp = (char*)strstr(lpbuf,"HTTP/1.1");
    if(!ptmp){
        printf("http/1.1 not faind\n");
        return NULL;
    }
    if(atoi(ptmp + 9)!=200){
        printf("result:\n%s\n",lpbuf);
        return NULL;
    }

    ptmp = (char*)strstr(lpbuf,"\r\n\r\n");
    if(!ptmp){
        printf("ptmp is NULL\n");
        return NULL;
    }
    response = (char *)malloc(strlen(ptmp)+1);
    if(!response){
        printf("malloc failed \n");
        return NULL;
    }
    strcpy(response,ptmp+4);
    return response;
}

char * http_post(const char *url,const char *post_str){

    char post[BUFFER_SIZE] = {'\0'};
    int socket_fd = -1;
    char lpbuf[BUFFER_SIZE*4] = {'\0'};
    char *ptmp;
    char host_addr[BUFFER_SIZE] = {'\0'};
    char file[BUFFER_SIZE] = {'\0'};
    int port = 0;
    int len=0;
	char *response = NULL;

    if(!url || !post_str){
        printf("      failed!\n");
        return NULL;
    }

    if(http_parse_url(url,host_addr,file,&port)){
        printf("http_parse_url failed!\n");
        return NULL;
    }
    //printf("host_addr : %s\tfile:%s\t,%d\n",host_addr,file,port);

    socket_fd = http_tcpclient_create(host_addr,port);
    if(socket_fd < 0){
        printf("http_tcpclient_create failed\n");
        return NULL;
    }
     
    sprintf(lpbuf,HTTP_POST,file,host_addr,port,strlen(post_str),post_str);

    if(http_tcpclient_send(socket_fd,lpbuf,strlen(lpbuf)) < 0){
        printf("http_tcpclient_send failed..\n");
        return NULL;
    }
	//printf("发送请求:\n%s\n",lpbuf);

    /*it's time to recv from server*/
    if(http_tcpclient_recv(socket_fd,lpbuf) <= 0){
        printf("http_tcpclient_recv failed\n");
        return NULL;
    }

    http_tcpclient_close(socket_fd);

    return http_parse_result(lpbuf);
}

char * http_get(const char *url)
{

    char post[BUFFER_SIZE] = {'\0'};
    int socket_fd = -1;
    char lpbuf[BUFFER_SIZE*4] = {'\0'};
    char *ptmp;
    char host_addr[BUFFER_SIZE] = {'\0'};
    char file[BUFFER_SIZE] = {'\0'};
    int port = 0;
    int len=0;

    if(!url){
        printf("      failed!\n");
        return NULL;
    }

    if(http_parse_url(url,host_addr,file,&port)){
        printf("http_parse_url failed!\n");
        return NULL;
    }
    //printf("host_addr : %s\tfile:%s\t,%d\n",host_addr,file,port);

    socket_fd =  http_tcpclient_create(host_addr,port);
    if(socket_fd < 0){
        printf("http_tcpclient_create failed\n");
        return NULL;
    }

    sprintf(lpbuf,HTTP_GET,file,host_addr,port);

    if(http_tcpclient_send(socket_fd,lpbuf,strlen(lpbuf)) < 0){
        printf("http_tcpclient_send failed..\n");
        return NULL;
    }
//	printf("发送请求:\n%s\n",lpbuf);

    if(http_tcpclient_recv(socket_fd,lpbuf) <= 0){
        printf("http_tcpclient_recv failed\n");
        return NULL;
    }
    http_tcpclient_close(socket_fd);

    return http_parse_result(lpbuf);
}



2008-12-10 17:59:00 zhoukuo1981 阅读数 599
  • Linux程序设计从入门到实战

    C/C++属于系统级别的编程语言,作为开源软件的代表作品Linux操作系统是所有C/C++程序员都应当熟悉和掌握的。本门课程从实战出发,降低了初级 C/C++程序员进入Linux程序设计的门槛。本门课程以Centos为实验环境,从核心命令讲解,再到gcc/gdb开发环境,直至覆盖到460多个常用的类Unix/POSIX API。本课可以有效的节约初学者上手Linxu操作系统的时间。同时,课程结合GNU的开源代码,仿真实现Linux常用命令,展现类Unix系统调用的工程级别的实现思路,重点讲解Linux环境下的开发和接口函数,多线程并发 ,并最终实现了一个带有CGI功能的小型http服务器。本课程结合计算机程序运行原理等内容,增加学员实际编程代码量,提升实战能力。

    1212 人正在学习 去看看 夏曹俊
Linux内核设计与实现 之 linux在线资源 

Linux内核官方网站
http://www.kernel.org/

Kernel Traffic.每周Linux内核邮件列表总结
http://www.kerneltraffic.org/
   
Linux Weekly News. 非常好的新闻网站,讨论每周内核发生的事,
http://www.lwn.net/

Kernel Newbies. 帮助内核黑客的社区项目
http://www.kernelnewbies.org/

Kernel.Org 内核官方资源库,包含大量核心内核黑客补丁
http://www.kernel.org

KernelTrap 包括所有内核相关的内容,尤其重点包括linux内核的内容。包括大量Linux内核开发的新闻和总结,还有大量与顶级内核开发者的访谈录 
http://www.kerneltrap.org/

OS News.Operating System News, 包括许多原创文章、访谈、见闻等。
http://www.osnews.com
    

2012-02-28 15:03:54 mifan88 阅读数 11519
  • Linux程序设计从入门到实战

    C/C++属于系统级别的编程语言,作为开源软件的代表作品Linux操作系统是所有C/C++程序员都应当熟悉和掌握的。本门课程从实战出发,降低了初级 C/C++程序员进入Linux程序设计的门槛。本门课程以Centos为实验环境,从核心命令讲解,再到gcc/gdb开发环境,直至覆盖到460多个常用的类Unix/POSIX API。本课可以有效的节约初学者上手Linxu操作系统的时间。同时,课程结合GNU的开源代码,仿真实现Linux常用命令,展现类Unix系统调用的工程级别的实现思路,重点讲解Linux环境下的开发和接口函数,多线程并发 ,并最终实现了一个带有CGI功能的小型http服务器。本课程结合计算机程序运行原理等内容,增加学员实际编程代码量,提升实战能力。

    1212 人正在学习 去看看 夏曹俊

       最近因为研究http协议的需要,在linux下面进行实验并抓取数据包进行相关验证。我们都知道,wireshark是一款windows下面非常流行的抓包工具。那么linux下面我们该怎么实现这个抓包过程呢。我通过几个步骤对其进行说明:

1.实验目的。

       在linux平台下,用C语言自己伪造http数据包,并发送给百度服务器请求其服务器主页。使用抓包工具抓取源客户端发出的数据包,验证其是否和真实的http数据包格式相吻合。

2.实验过程

      1)linux上面下载安装tcpdump工具并抓取数据包

                 抓包命令为:tcpdump  -s 0 tcp port 80 -w   loghttp.cap  (存储抓包信息的文件名)             

      2)实现linux与windows的文件共享

                 主要使用samba实现。

      3)windows下面安装wireshark抓包工具

                 直接在官方网站就可以下载到

      4)在windows下面用wireshark工具打开linux上面tcpdump抓取的数据包

                 打开自己的往上邻居,在里面找到samba服务器 就可以找到共享的文件夹。

 3.现在我们就可以在wireshark图形界面工具中,对我们自己的http包进行查看分析了,如果不合格的话,可以再进行加工改造,直到和一般的http相差无几。 

没有更多推荐了,返回首页