标签归档:c

小菜瞎搞HTTP–简单GET请求

//
//  main.c
//
//  Created by qixingyue on 13-7-19.
//  Copyright (c) 2013年 qixingyue. All rights reserved.
//

#include <stdio.h>
#include <unistd.h>
#include <string.h>

//socket 程序需要的头文件
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, const char * argv[])
{
    if(argc != 5 ) {
        printf("Error Happend. Params not enough.\n");
        return 1;
    }
    
    printf("Get FILE:%s from %s User: %s , Passowrd : %s",argv[4],argv[1],argv[2],argv[3]);
    
    int client_socket ;
    char buffer[1000];
    
    if((client_socket = socket(AF_INET, SOCK_STREAM, 0))<0) {
        printf("Socket create error . \n");
        return 1;
    }
    
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port =  htons(80) ;
    serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    
    if(connect(client_socket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0 ) {
        printf("Connect Error:\n");
        return 1;
    }
    
    
    char *first_line = "GET / HTTP/1.1\n";
    char *second_line = "Host: itianmen.com\n";
    send(client_socket, first_line,strlen(first_line),0);
    send(client_socket, second_line,strlen(second_line),0);
    send(client_socket, "\n", 1,0);
    
    while(recv(client_socket, buffer, 1000, 0) >0 ){
        printf("GET MESSAGE : %s \n",buffer);
    }
    
    close(client_socket);
    return 0;
}

c语言exec系列的几个函数

int execl( const char *path, const char *arg, …);
int execlp( const char *file, const char *arg, …);
int execle( const char *path, const char *arg , …, char* const envp[]);
int execv( const char *path, char *const argv[]);
int execvp( const char *file, char *const argv[]);

首个ADT栈实现

ADT是抽象数据类型,其他语言中面向对象的体现,也是这个东西吧!

首先应该看明白C语言如何进行模块化吧!可以参看《c语言程序模块化》这篇文章。

ADT其实也是一种特殊的模块,所以,和上篇中的一个模块很类似,只是定义了一种新的类型吧!

对外通信仍然是用.h文件来完成,可以看作,开发与制作者之间通信的一种协议吧!

在.h当中定义一个结构体的指针类型,注意是指针类型,这个有点儿说法,因为,类型需要对外公开,但是不能让外部知道结构内部的细节,所以用不确定类型来完成这个功能。

对外而言,看到的只是这么一个类型,对内部的结构一无所知,开发部分,实现这个结构的具体细节。这也是解除耦合性的一大体现。

下边还是一个例子吧:与那篇文章中的例子,类似,只是这次用ADT来实现,这样就可以用很多栈的结构。

stack_adt.h

#ifndef STACK_ADT_H

   #define STACK_ADT_H

   typedef struct stack_type *Stack;

   Stack create(void);

   void destroy(Stack s);

   void make_empty(Stack s);

   int is_empty(Stack s);

   int is_full(Stack s);

   void push(Stack s, int i);

   int pop(Stack s);

   void show_stack(Stack s);

#endif

stack_type是一个不确定类型,在另一个文件中声明。不同于模块化,因为,有可能有很多Stack的例子,所以,需要提供create和destroy的方法。有点儿类似,面向对象编程中的构造函数和析构函数,只是他们不是自己调用的,而是客户程序员,必须调用的。否则,容易出现问题了。为了查看栈中的数据,添加了show_stack方法。

stack_adt.c

#include "stack_adt.h"
#include <stdio.h>
#include <stdlib.h>


#define STACK_SIZE 100

struct stack_type {
   int contents[STACK_SIZE];
   int top;
};

static void terminate(char *message){
   printf("%s",message);
   exit(EXIT_FAILURE);
}

Stack create(void) {
   Stack s = malloc(sizeof(struct stack_type));
   if(s == NULL){
     terminate("Error in create: stack could not be created!");
   }
   s->top=0;
   return s;
}

void destroy(Stack s) {
  free(s);
}

void make_empty(Stack s) {
  s->top=0;
}

int is_empty(Stack s){
  return s->top == 0 ;
}

int is_full(Stack s) {
   return s->top == STACK_SIZE;
}

void push(Stack s , int i) {
   if(is_full(s)){
     terminate("Stack is full!");
   }
   s->contents[s->top++] = i; 
}

int pop(Stack s) {
   if(is_empty(s)){
      terminate("Stack is empty!");
   }
   return s->contents[--s->top];
}

void show_stack(Stack s){
  int i;
  for(i=0;i<s->top;i++){
    printf("%d\t",s->contents[i]);
    if(i%6) {
      printf("\n");
    }
  }
}

实现与上一篇文章中基本类似,只是将所有的操作,都集中到了一个Stack结构的实例当中。
main.c

#include "stack_adt.h"
#include <stdio.h>
int main(int argc, char **argv){
   int i;
   Stack s;
   s = create();
   scanf("%d",&i);
   while(i){
     push(s,i%2);
     i = i/2;
   }
   while(!is_empty(s)){
     printf("%d",pop(s));
   }
   printf("\n");
   return 0;
}

仍然是实现二进制的转换程序。