1. 程式人生 > >基於http協議的C語言客戶端程式碼

基於http協議的C語言客戶端程式碼

轉載者注:網上原檔案有個小bug,下面貼的是已修復後的程式碼

/******* http客戶端程式 httpclient.c ************/
#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>

//////////////////////////////httpclient.c 開始///////////////////////////////////////////

/********************************************
  功能:搜尋字串右邊起的第一個匹配字元
 ********************************************/
char * Rstrchr(char * s, char x) {
	int i = strlen(s);
	if(!(*s)) return 0;
	while(s[i-1]) if(strchr(s + (i - 1), x)) return (s + (i - 1)); else i--;
	return 0;
}

/**************************************************************
  功能:從字串src中分析出網站地址和埠,並得到使用者要下載的檔案
 ***************************************************************/
void GetHost(char * src, char * web, char * file, int * port) {
	char * pA;
	char * pB;
	memset(web, 0, sizeof(web));
	memset(file, 0, sizeof(file));
	*port = 0;
	if(!(*src)) return;
	pA = src;
	if(!strncmp(pA, "http://", strlen("http://"))) pA = src+strlen("http://");
	else if(!strncmp(pA, "https://", strlen("https://"))) pA = src+strlen("https://");
	pB = strchr(pA, '/');
	if(pB) {
		memcpy(web, pA, strlen(pA) - strlen(pB));
		if(pB+1) {
			memcpy(file, pB + 1, strlen(pB) - 1);
			file[strlen(pB) - 1] = 0;
		}
	}
	else memcpy(web, pA, strlen(pA));
	if(pB) web[strlen(pA) - strlen(pB)] = 0;
	else web[strlen(pA)] = 0;
	pA = strchr(web, ':');
	if(pA) *port = atoi(pA + 1);
	else *port = 80;
}

/*********************************************************************
 *filename: httpclient.c
 *purpose: HTTP協議客戶端程式,可以用來下載網頁
 *wrote by: zhoulifa(
[email protected]
) 周立發(http://zhoulifa.bokee.com) Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言 *date time:2006-03-11 21:49:00 *Note: 任何人可以任意複製程式碼並運用這些程式碼,當然包括你的商業用途 * 但請遵循GPL *********************************************************************/ 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); } printf("parameter.1 is: %s\n", argv[1]); GetHost(argv[1], host_addr, host_file, &portnumber);/*分析網址、埠、檔名等*/ printf("webhost:%s\n", host_addr); printf("hostfile:%s\n", host_file); printf("portnumber:%d\n\n", portnumber); if((host=gethostbyname(host_addr))==NULL)/*取得主機IP地址*/ { fprintf(stderr,"Gethostname error, %s\n", strerror(errno)); exit(1); } /* 客戶程式開始建立 sockfd描述符 */ 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,將要傳送給主機*/ /*取得真實的檔名*/ if(host_file && *host_file) pt = Rstrchr(host_file, '/'); else pt = 0; memset(local_file, 0, sizeof(local_file)); if(pt && *pt) { if((pt + 1) && *(pt+1)) strcpy(local_file, pt + 1); else memcpy(local_file, host_file, strlen(host_file) - 1); } else if(host_file && *host_file) strcpy(local_file, host_file); else strcpy(local_file, "index.html"); printf("local filename to write:%s\n\n", local_file); /*傳送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); } //////////////////////////////httpclient.c 結束///////////////////////////////////////////

相關推薦

基於http協議C語言客戶程式碼

轉載者注:網上原檔案有個小bug,下面貼的是已修復後的程式碼 /******* http客戶端程式 httpclient.c ************/ #include <stdio.h> #include <stdlib.h> #include

linux下C語言程式設計日誌(1):基於TCP協議的伺服器/客戶程式

  基於TCP協議的伺服器/客戶端程式  首先我們看一下使用TCP協議進行網路通訊的程式基本模型:伺服器首先進行初始化操作:呼叫函式socket建立一個套接字,函式bind將這個套接字與伺服器的公認地址繫結在一起,函式listen將這個套接字換成傾聽套接字,然後呼叫函式acc

Java基於TCP協議的Socket客戶檔案上傳與下載

import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.F

http協議C語言程式設計實現

轉載:http://zhoulifa.bokee.com/4640913.html 大家都很熟悉HTTP協議的應用,因為每天都在網路上瀏覽著不少東西,也都知道是HTTP協議是相當簡單的。每次用到FlashGet之類的下載軟體下載網頁,當用到那個“用FlashGet下載全部連

基於UDP協議的伺服器/客戶

基於UDP協議的客戶端/伺服器是不可靠的,無連線的,所以相比於TCP來說,伺服器端就不需要listen和accept操作,而客戶端也就不需要connect操作。 先來認識一下UDP socket裡的兩

基於TCP協議的伺服器/客戶程式

作為傳輸層的主要協議,TCP協議不僅可以支援本地的資料通訊,還可以支援跨網路的程序間通訊。 在偌大的網際網路中,我們可以通過“IP地址+端⼜號”標識網際網路中唯一的一個程序。然而,“IP地址+端⼜號”就稱為socket,這就是網路socket程式設計。 在TCP協議中,建⽴

一種基於GB28181協議的國標客戶實現

其中,有一個UML圖,是關於架構設計總體構思的: 依據這張圖我們看到,GB28181的信令服務和國標客戶端在協議棧層面上是一直的。基於此,筆者團隊設計並開發了針對GB28181的一個客戶端實現。並將其以SDK的形式進行了封裝,可供使用者進行二次開發,以便客戶能夠集中精

Redis C語言客戶庫hiredis文件翻譯

Hiredis是redis資料庫一個輕量的C語言客戶端庫。 之所以輕量是由於它只是簡單的提供了對redis操作語句支援的介面,並沒有實現具體的操作語句的功能。但正是由於這種設計使我們只要熟悉了通用的redis操作語句就可以很容易的使用該庫和redis資料庫進行互動。 除了支

HTTP協議規定,客戶的編寫

name zip 基礎上 ive 分隔 pre ringbuf use append HTTP協議是網絡應用層協議,建立在TCP/IP協議基礎上。HTTP協議基於客戶/服務器模式,客戶端主動發出HTTP請求,服務器接收HTTP請求,返回HTTP響應結果。HTTP協議對HTT

api介面對於客戶的身份認證方式以及安全措施 基於http協議的api介面對於客戶的身份認證方式以及安全措施

轉載 基於http協議的api介面對於客戶端的身份認證方式以及安全措施  由於http是無狀態的,所以正常情況下在瀏覽器瀏覽網頁,伺服器都是通過訪問者的cookie(cookie中儲存的jsessionid)來辨別客戶端的身份的,當客戶端進行登入伺服器也會將登入資訊存放在伺服器並與客戶端的coo

C#.網路程式設計 Socket基礎(四) WPF系統Socket TCP協議 伺服器與客戶 不同型別檔案傳輸,同時解決UI執行緒與工作執行緒的卡頓問題

一、簡介 雖然,本文的前面幾篇文章在WinForm中實現了Socket TCP協議 伺服器與客戶端 不同型別檔案傳輸,詳情見 但是,卻沒有在WPF中實現 Socket TCP協議 伺服器與客戶端 不同型別檔案傳輸。因此,本文將描述如何在WPF中實現該功能。

基於Socket的服務多執行緒模式——服務客戶程式碼

本文程式碼來源於《實戰java高併發程式設計》葛一鳴 郭超 著 學習這本書的過程中,感覺這一部分比較重要,自己做下總結,也希望能給大家提供些幫助。       本程式碼模擬簡單的Echo伺服器,對於Echo伺服器,他會讀取客戶端的一個輸入,並將這個輸入原

SSL握手通訊詳解及linux下c/c++ SSL Socket(另附SSL雙向認證客戶程式碼)

SSL(Secure Sockets Layer 安全套接層),及其繼任者傳輸層安全(Transport Layer Security,TLS)是為網路通訊提供安全及資料完整性的一種安全協議。TLS與SSL在傳輸層對網路連線進行加密。   安全證書既包含了用於加密資料的金鑰

PC軟體開發技術之二:用C#開發基於自動化介面的OPC客戶

OPC全稱是Object Linking and Embedding(OLE) for Process Control,它的出現為基於Windows的應用程式和現場過程控制應用建立了橋樑。OPC作為一整套介面、屬性和方法的協議標準集,與具體的開發語言沒有關係。 1、OPC客戶端介面方式

C# 完整的UDP客戶程式碼 組播+單播 非同步+同步

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; u

WebService基於Eclipse的客戶程式碼生成

很多剛剛接觸WebService的人對於生成客戶端的呼叫程式碼很懵懂,下面我就獻醜一小下: 1.首先我先新建了一個WebService專案: 簡單的介面以及實現類的,之後我們就掛起這個專案,得到我們需要給出的wsdl 好,我們所要訪問的所有資訊都在這個裡邊,但是我

C++基於TCP/IP簡單的客戶、伺服器通訊程式例項

本篇文章實現了一個基於TCP 的一個非常簡單的客戶/伺服器通訊程式例項。該程式中通訊協議使用的是面向連線的TCP協議SOCK_STREAM, 伺服器的ip地址為本地地址即: 127.0.0.1,埠號為自定義的5099(大於1024即可),服務端的功能只要有客戶

基於RTOS的c語言實現http檔案上傳

本實驗為了減少程式碼量,使用了封裝比較完善的http庫,本文主要講述http檔案上傳的主要要求。 一、分析http關鍵頭部資訊 為了分析http header,我們通過chrome得到上傳檔案時的http資訊: 通過上面的截圖我們可以發現,關鍵頭部

swagger-codegen生成java客戶程式碼(其他語言類似)

<dependency>   <groupId>io.swagger</groupId>   <artifactId>swagger-jaxrs</artifactId>   <version>1.5.9</version>

Protobuf二進位制檔案基於Http協議傳輸的應用例項 ☞ Python與Java之間無關語言的資料傳輸

       在前兩篇中,博主介紹了Google Protocol Buffer【一種資料互動格式】在Python和Java中各自的應用例項,重點就是掌握和理解如何構造protobuf的協議檔案.proto:檔案中的資料組織結構是以messgae打頭的,message訊息體裡