windows下的http简单例子。

本文介绍了一个使用socket编程技术从指定URL获取网页内容,并从中提取所有href标签包含的链接,最终将这些链接保存到文件中的过程。通过解析HTTP响应,作者实现了链接的过滤和存储功能。

最近在网上东找西找,才找到了几个windows下用socket实现http的例子,然后改动一番,就可以编译通过了。

代码实现的功能是打开一个url,将该地址的href标签包含的链接过滤出来 保存在一个文件里面,本人c和c++都不精,只能这么混着用了,各位不要笑话偶哦~~

废话不多说,上代码:

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <errno.h>
#include <vector>


using namespace std;


#pragma comment( lib , "ws2_32.lib")
#define BUF_SIZE 1024*1024
#define DEF_HOSTNAME "www.baidu.com"
#define HEAD_TAG  "href=\""


vector<string> v_urls; 



void find_link(char *buffer, vector<string> &v_urls)
{
char * pos =  strstr(buffer,HEAD_TAG);
while( pos )
{
pos +=strlen(HEAD_TAG);
const char * nextQ = strstr( pos, "\"" );
if( nextQ )
{
char * url = new char[ nextQ-pos+1 ];
sscanf( pos, "%[^\"]", url);
string s = url;
v_urls.insert(v_urls.end(),url);
pos = strstr(pos, HEAD_TAG);
delete [] url;
}

}




}


int main( int argc , char** argv )
{
WSADATA wsaData;


int len , maxLen;
char* bufMsg;
char* strHost;
char* ptr;
FILE* page;


HOSTENT* pHostent;
SOCKET sock;
SOCKADDR_IN addr;
TIMEVAL timeout;
fd_set fd;



//启动网络服务
if( WSAStartup( 0x101 , &wsaData ) != 0 ){
printf( "error:%d,启动网络服务失败" , WSAGetLastError() );
return 1;
}


//解析域名
if( argc > 1 ){
strHost = argv[1];
}
else{
strHost = DEF_HOSTNAME;
}


printf( "Host:%s\n" , strHost );


pHostent = gethostbyname( strHost);
if( pHostent == NULL ){
printf( "error:%d,解析域名失败" , WSAGetLastError() );
return 1;
}
memset( &addr , 0 , sizeof( SOCKADDR_IN ) );
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
addr.sin_addr.s_addr = *(unsigned long*)pHostent->h_addr ;


printf( "IP:%s\n" , inet_ntoa(addr.sin_addr) );


//建立连接 
sock = socket( AF_INET , SOCK_STREAM , 0 );
if( sock == INVALID_SOCKET ){
printf( "error:%d,建立socket失败" , WSAGetLastError() );
return 1;
}


if( connect( sock , (SOCKADDR*)&addr , sizeof( SOCKADDR ) ) == SOCKET_ERROR ){
printf( "error:%d,连接失败" , WSAGetLastError() );
return 1;
}


//发送请求
bufMsg= (char*)calloc( BUF_SIZE , sizeof( char ) );
if( bufMsg== NULL ) {
printf( "error:%d,分配内存失败" , errno );
return 1;
}
sprintf(bufMsg,"GET http://%s:%d HTTP/1.1\r\nHost:%s:%d\r\nAccept:  */*\r\nConnection: close\r\n\r\n",strHost ,80,strHost ,80);
printf( "MSG:%s" , bufMsg );


len = send( sock , bufMsg , strlen( bufMsg ) , 0 );
if( len == strlen( bufMsg ) ){
printf( "请求成功\n" );
}
else{
printf( "请求失败\n" );
}


//下载页面
memset( bufMsg , 0 , len );
ptr = bufMsg ;
maxLen = BUF_SIZE - 1 ;


printf( "下载中...\n" );


do{
timeout.tv_sec = 2;
timeout.tv_usec = 0;


FD_ZERO( &fd );
FD_SET( sock , &fd );


if( select( sock+1 , &fd , NULL , NULL ,&timeout ) < 0 ){
printf( "error:%d,下载失败" , WSAGetLastError() );
break;
}


if( FD_ISSET( sock , &fd ) ){


len = recv( sock , ptr , maxLen , 0 );


if( len == 0 ){
printf( "下载完毕\n" );
break;
}
else if(len == -1 ){
printf( "error:%d,下载错误" , WSAGetLastError() );
break;
}


maxLen -= len;
if( maxLen <= 0 ) {
printf( "缓冲区满了n" );
break;
}


ptr += len;
}
}while( 1 );


closesocket( sock );
WSACleanup( );


       //保存页面
ptr = strstr( bufMsg , "\r\n\r\n" );
ptr += 4;


page = fopen( "page.txt" , "w" );
if( page == NULL ) {
printf( "error:%d,打开文件失败" , errno ) ;
return 1;
}
find_link(ptr,v_urls);
for(int j=0; j<v_urls.size(); j++)
{
fwrite(v_urls.at(j).c_str(),sizeof(char),strlen(v_urls.at(j).c_str()),page);
fwrite("\n",1,1,page);
}

fclose( page );
free( bufMsg);


return 0;
}

### Windows 下 C 语言 `flock` 函数使用示例 需要注意的是,在 Windows 平台上并没有直接提供 Unix/Linux 中的 `flock()` 系统调用。为了实现类似的文件锁定功能,通常会使用 Win32 API 提供的相关接口来替代。 对于想要在 Windows 上模拟 `flock` 行为的情况,可以考虑使用 `_locking` 或者更底层的 CreateFile 和 LockFileEx 来完成相似的功能[^1]。 下面是一个基于 MSVC 的简单例子,展示如何通过 Win32 API 实现类似于 Linux 下 flock 的行为: ```c #include <windows.h> #include <stdio.h> void main() { HANDLE hFile; OVERLAPPED overlapped = {0}; // 打开或创建一个测试文件 hFile = CreateFile( "testfile.txt", // 文件名 GENERIC_READ | GENERIC_WRITE, // 访问模式 FILE_SHARE_READ, // 共享模式 NULL, // 安全属性 OPEN_ALWAYS, // 创建方式 FILE_ATTRIBUTE_NORMAL, // 属性标志 NULL // 模板句柄 ); if (hFile == INVALID_HANDLE_VALUE) { printf("无法打开文件\n"); return; } // 尝试获取独占锁 if (!LockFile(hFile, 0, 0, 1, 0)) { printf("加锁失败:%d\n", GetLastError()); } else { printf("成功获得文件锁。\n"); Sleep(5000); // 模拟处理时间 UnlockFile(hFile, 0, 0, 1, 0); printf("已释放文件锁。\n"); } CloseHandle(hFile); } ``` 此程序尝试对名为 testfile.txt 的文件施加一个字节范围内的独占锁(即整个文件),并保持该状态五秒钟后再解除锁定。如果其他应用程序试图在此期间对该部分文件进行写入,则会被阻塞直到当前进程释放了这个区域上的锁为止[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值