学习socket从这里开始1
首先介绍一个socket获取天气服务的实例,随后我会逐步的使用小安派实现socket 链接天气服务
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#define PORT "80"
#define HOST "api.seniverse.com"
int main()
{
// 初始化 addrinfo 结构体,用于指定要连接的服务器的信息
struct addrinfo hints, *servinfo, *p;
int rv, sockfd;
char request[256];
char buffer[1024];
int numbytes;
int found_start = 0;
// 清空 hints 结构体,设置地址族为不指定,套接字类型为流式套接字(TCP)
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
// 获取指定主机和服务的信息,存储在 servinfo 链表中
if ((rv = getaddrinfo(HOST, PORT, &hints, &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// 遍历 servinfo 链表,尝试创建并连接套接字
for (p = servinfo; p != NULL; p = p->ai_next)
{
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
{
continue;
}
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1)
{
close(sockfd);
continue;
}
break;
}
// 如果没有成功连接到任何地址,输出错误信息并退出
if (p == NULL)
{
fprintf(stderr, "failed to connect\n");
return 2;
}
// 释放 servinfo 结构体占用的内存
freeaddrinfo(servinfo);
// 构造 HTTP GET 请求字符串
snprintf(request, sizeof(request), "GET /v3/weather/now.json?key=SOGXnVRmQE-ISnQRo&location=hangzhou&language=zh-Hans&unit=c HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", HOST);
// 发送 HTTP 请求到服务器
send(sockfd, request, strlen(request), 0);
// 接收服务器返回的数据,直到没有更多数据可接收
while ((numbytes = recv(sockfd, buffer, sizeof(buffer) - 1, 0)) > 0)
{
buffer[numbytes] = '\0';
// 如果还没有找到 JSON 数据的开始部分
if (!found_start)
{
// 查找第一个 '{' 的位置
char *start = strchr(buffer, '{');
if (start != NULL)
{
found_start = 1;
printf("%s", start);
}
else
{
// 如果这一块数据中没有找到 '{',继续接收下一块数据
continue;
}
}
else
{
// 如果已经找到 JSON 数据的开始部分,直接打印
printf("%s", buffer);
}
}
// 关闭套接字
close(sockfd);
return 0;
}
在linux环境下 gcc main.c -o main
./main
就可以看到天气了
