posts - 297,  comments - 15,  trackbacks - 0

程序是从http://zhoulifa.bokee.com/4640913.html 下的,做了些裁剪,使程序更加的清晰
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>
#include <limits.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ctype.h>

int main(int argc, char *argv[])
{
int sockfd;
char buffer[1024];
struct sockaddr_in server_addr;
struct hostent *host;
int portnumber,nbytes;
char host_addr[256];
char host_file[1024];
char local_file[256];
FILE * fp;
char request[1024];
int send, totalsend;
int i;
char * pt;

if(argc!=2)
{
    fprintf(stderr,"Usage:%s web-address\a\n",argv[0]);
    exit(1);
}
portnumber=80;
strcpy(host_addr,argv[1]);
if((host=gethostbyname(argv[1]))==NULL)/*取得主机IP地址*/
{
    fprintf(stderr,"Gethostname error, %s\n", strerror(errno));
    exit(1);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)/*建立SOCKET连接*/
{
    fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
    exit(1);
}
/* 客户程序填充服务端的资料 */
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(portnumber);
server_addr.sin_addr=*((struct in_addr *)host->h_addr);

/* 客户程序发起连接请求 */
if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)/*连接网站*/
{
    fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
    exit(1);
}

sprintf(request, "GET /%s HTTP/1.1\r\nAccept: */*\r\nAccept-Language: zh-cn\r\n\
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\r\n\
Host: %s:%d\r\nConnection: Close\r\n\r\n", host_file, host_addr, portnumber);
printf("%s", request);/*准备request,将要发送给主机*/

/*取得真实的文件名*/
strcpy(local_file, "index.html");
/*发送http请求request*/
send = 0;totalsend = 0;
nbytes=strlen(request);
while(totalsend < nbytes) {
    send = write(sockfd, request + totalsend, nbytes - totalsend);
    if(send==-1) {printf("send error!%s\n", strerror(errno));exit(0);}
    totalsend+=send;
    printf("%d bytes send OK!\n", totalsend);
}

fp = fopen(local_file, "a");
if(!fp) {
    printf("create file error! %s\n", strerror(errno));
    return 0;
}
printf("\nThe following is the response header:\n");
i=0;
/* 连接成功了,接收http响应,response */
while((nbytes=read(sockfd,buffer,1))==1)
{
    if(i < 4) {
      if(buffer[0] == '\r' || buffer[0] == '\n') i++;
      else i = 0;
      printf("%c", buffer[0]);/*把http头信息打印在屏幕上*/
    }
    else {
      fwrite(buffer, 1, 1, fp);/*将http主体信息写入文件*/
      i++;
      if(i%1024 == 0) fflush(fp);/*每1K时存盘一次*/
    }
}
fclose(fp);
/* 结束通讯 */
close(sockfd);
exit(0);
}


1    struct hostent *gethostbyname(const char *name);

     这个函数完成进行域名和IP地址的转换,返回的为:

      struct hostent {
      char *h_name;                      /* 主机的官方域名 */
      char **h_aliases;                  /* 一个以NULL结尾的主机别名数组 */
      int h_addrtype;                     /* 返回的地址类型,在Internet环境下为AF-INET */
     int h_length;                         /*地址的字节长度 */
     char **h_addr_list;                /* 一个以0结尾的数组,包含该主机的所有地址*/ 
      }; 
     #define h_addr h_addr_list[0]           /*在h-addr-list中的第一个地址*/

    我们一般用的也就第一个地址

2   接下去就是SOCKET 的建立,绑定,连接,我们想要连接,上面得到的ip地址是不行的,我们要使用服务器的地址,具体数据结构如下:

   struct sockaddr_in {
      short int sin_family;                                           /* 地址族 */
      unsigned short int sin_port;                              /* 端口号 */
      struct in_addr sin_addr;                                   /* IP地址 */ 上面得到的地址
      unsigned char sin_zero[8];                              /* 填充0 以保持与struct sockaddr同样大小 */
      };

   这里也提下 struct sockaddr 这个是描述sock 地址信息的,和上面的结构大小一样,可以相互转换

   struct sockaddr {
       unsigned short sa_family; /* 地址族, AF_xxx */
        char sa_data[14]; /* 14 字节的协议地址 */
       }

3 我们和服务器连上之后,就可以向服务器发送请求了

     write(sockfd, char *, size);      内容就是:GET /%s HTTP/1.1\r\nAccept: */*\r\nAccept-Language: zh-cn\r\n\User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\r\n\
Host: %s:%d\r\nConnection: Close\r\n\r\n

   具体是由其协议定的,我也还不是很清楚

4 服务器响应,就会发来信息头+ 实际页面的信息, 这个中间是有4个("\r"或"\n")进行分开的。

转自:
http://blog.chinaunix.net/u2/76292/showart_1335922.html

posted on 2009-12-07 23:12 chatler 阅读(535) 评论(0)  编辑 收藏 引用 所属分类: Socket

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2009年12月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用链接

留言簿(10)

随笔分类(307)

随笔档案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感觉这个博客还是不错,虽然做的东西和我不大相关,觉得看看还是有好处的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新评论

阅读排行榜

评论排行榜