问题如题
我在网上了解到该错误是连接超时,但不明白为什么如此,也不知道如何解决,求学长解难!
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
//http://www.netbian.com/meinv/ 测试网址
bool parseUrl(const char* url,char*host,char*resPath)
{
if (!url)
return false;
//解析主机名,常说的网址
//http://pic.yesky.com/364/585172864.shtml
const char* substr = strstr(url, "//");
if (substr)
{
substr += 2;
}
//pic.yesky.com/364/585172864.shtml
else
{
substr = url;
}
const char* substr1 = strstr(substr, "/");
if (substr1)
{
host ? strncpy(host, substr, substr1 - substr) : NULL;
resPath ? strcpy(resPath, substr1) : NULL;
}
else
{
host ? strcpy(host, substr) : NULL;
resPath ? strcpy(resPath, "/") : NULL;
}
printf("Host:%s ResourcePath:%s\n", host, resPath);
}
typedef struct Spider
{
char host[256]; //主机名 网站pic.yesky.com
char path[256]; // /hello.png
SOCKET fd; //服务器socket
}Spider;
void Spider_parseUrl(Spider* spider, const char* url)
{
memset(spider->host, 0, sizeof(spider->host));
memset(spider->path, 0, sizeof(spider->path));
//解析主机名,常说的网址
//http://pic.yesky.com/364/585172864.shtml
const char* substr = strstr(url, "//");
if (substr)
{
substr += 2;
}
//pic.yesky.com/364/585172864.shtml
else
{
substr = url;
}
const char* substr1 = strstr(substr, "/");
if (substr1)
{
strncpy(spider->host, substr, substr1 - substr);
strcpy(spider->path, substr1);
}
else
{
strcpy(spider->host, substr);
strcpy(spider->path, "/");
}
//puts(substr); // //pic.yesky.com/364/585172864.shtml
//puts(spider->path); // /364/585172864.shtml
//puts(spider->host); // pic.yesky.com\3
printf("Host:%s ResourcePath:%s\n", spider->host, spider->path);
}
static bool spider_connect(Spider* spider)
{
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd == SOCKET_ERROR)
{
printf("error %d", WSAGetLastError());
return false;
}
//通过网址获取ip
HOSTENT* host = gethostbyname(spider->host);
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
//addr.sin_addr.S_un.S_addr = inet_addr("103.72.145.79");
//addr.sin_addr = *((IN_ADDR*)host->h_addr_list[0]);
memcpy(&addr.sin_addr, host->h_addr, sizeof(IN_ADDR));
if (SOCKET_ERROR == connect(fd, (SOCKADDR*)&addr, sizeof(addr)))
{
printf("error %d", WSAGetLastError());
return false;
}
printf("连接成功!\n");
spider->fd = fd;
return true;
}
void Spider_downloadImage(Spider* spider)
{
if (strlen(spider->host) == 0 || strlen(spider->path) == 0)
{
printf("[error] 请先解析Url~~\n");
return;
}
//链接服务器
if (!spider_connect(spider))
{
return;
}
//发送请求
static char str[1024] = { 0 };
sprintf(str, "GET %s HTTP/1.1\r\n", spider->path);
sprintf(str + strlen(str), "Host:%s\r\n", spider->host);
strcat(str, "Connection:Close\r\n");
//strcat(str, "Content-Type:text/html,image/jpeg;charset=utf-8\r\n");
//strcat(str, "Content-Type:image/png\r\n");
strcat(str, "\r\n");
printf("req %s\n", str);
send(spider->fd, str, strlen(str), 0);
//获取图片名
char filename[128] = { 0 };
char *pf = strrchr(spider->path, '/');
if (!pf)
{
strcpy(filename, "maye.png");
}
else
{
strcpy(filename, pf+1);
}
printf("filename %s\n", filename);
//接受图片并保存
FILE* fp = fopen(filename, "wb");
if (!fp)
return;
char buf[1024] = { 0 }; //接受到的数据
int len = 0; //接受到多少字节
//去掉响应头 "\r\n\r\n" 及之前的都是响应头
len = recv(spider->fd, buf, 1023, 0);
char* p = strstr(buf, "\r\n\r\n");
if (!p)
return;
p += 4; //跳过\r\n\r\n
fwrite(p, sizeof(char), len - (p - buf),fp);
while (true)
{
len = recv(spider->fd, buf, 1023, 0);
if (len > 0)
{
fwrite(buf, sizeof(char), len, fp);
}
else
{
break;
}
}
fclose(fp);
}
int main1(int argc, char* argv[])
{
//system("chcp 936"); //临时修改控制台编码 936 gbk 65001 utf-8
Spider s;
////Spider_init(&s, "https://pic.yesky.com/");
//Spider_init(&s, "www.baidu.com");
////解析资源
//char* res = Spider_request(&s,NULL);
//printf("recv %s", res);
FILE* fp = fopen("log.html", "w");
//fputs(res, fp);
fclose(fp);
const char* tt = "<a href=\"http://pic.yesky.com/212/584241212.shtml\" target=\"_self\"><img src=\"http://d-pic-image.yesky.com/113x113//uploadImages/2018/302/51/ND7852YE0R3F.JPG\"alt=\"红裙美女意境写真摄影 仙女气息十足!_小清新\"/></a><span class=\"num\">";
//下载内容
// spider_downloadImage(&s,res);
return 0;
}
int main(int argc, char* argv[])
{
Spider sp;
Spider_parseUrl(&sp, "//www.baidu.com/img/flexible/logo/pc/index.png");
Spider_downloadImage(&sp);
return 0;
}
运行结果如下
我们知道:原码的表示方法:最高位作为符号位,不表示数据,0为正,1为负。
比如 [+1] = [0000 0001] (原码) [-1] = [1000 0001] (原码)
反码:正数和原码相同,负数:符号位不变,其余数位取反
[+1] = [0000 0001] (反码) [-1] = [1111 1110] (反码)
补码:正数和原码相同,负数:符号位不变,其余数位取反+1
[+1] = [0000 0001] (补码) [-1] = [1111 1111] (补码)
所以到这里,基本出来了,-1对于带符号型(以8位为例)来说用补码表示自然就是 1111 1111
对于不带符号整数来说,最高位不表示符号位,故表示255 这也是unsigned回绕机制的原理。说到底,还是计算机底层表示