Skip to content

Instantly share code, notes, and snippets.

@ssrlive
Last active April 15, 2020 13:22
Show Gist options
  • Save ssrlive/1a63cef88209d0d4a5c9cfffaa62f484 to your computer and use it in GitHub Desktop.
Save ssrlive/1a63cef88209d0d4a5c9cfffaa62f484 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#if defined(WIN32) || defined(_WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdint.h>
#pragma comment(lib,"ws2_32.lib") // Winsock Library
#else
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define closesocket close
#endif
int socket_connect(const char *host, uint16_t port){
struct hostent *hp;
struct sockaddr_in addr = { 0 };
int on = 1, sock;
if ((hp = gethostbyname(host)) == NULL) {
return -1;
}
memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
addr.sin_port = htons(port);
addr.sin_family = hp->h_addrtype;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
return -1;
}
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&on, sizeof(int));
if (connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
closesocket(sock);
return -1;
}
return sock;
}
#define BUFFER_SIZE 1024
typedef void (*FN_recv_data)(uint8_t *data, size_t len, void *p);
void launch_web_request(const char *host, uint16_t port, const char *request_head, FN_recv_data cb, void *p) {
int fd = -1;
char buffer[BUFFER_SIZE] = { 0 };
size_t count = 0;
#ifdef _WIN32
static int WSAStartup_flag = 0;
if (WSAStartup_flag == 0) {
WSADATA wsa = { 0 };
WSAStartup(MAKEWORD(2,2), &wsa);
WSAStartup_flag = 1;
}
#endif
do {
if (cb == NULL) {
break;
}
if (request_head) {
strcpy(buffer, request_head);
} else {
sprintf(buffer, "GET / HTTP/1.0\r\nHost: %s\r\n\r\n", host);
}
fd = socket_connect(host, port);
if (fd < 0) {
break;
}
if (send(fd, buffer, strlen(buffer), 0) < 0) {
break;
}
memset(buffer, 0, BUFFER_SIZE);
while ( (count = (size_t) recv(fd, buffer, BUFFER_SIZE - 1, 0)) > 0) {
cb((uint8_t*)buffer, count, p);
memset(buffer, 0, BUFFER_SIZE);
}
} while (0);
if (fd > 0) {
#if !defined(SHUT_RDWR)
#define SHUT_RDWR 2
#endif
shutdown(fd, SHUT_RDWR);
closesocket(fd);
}
#ifdef _WIN32
#if 0
WSACleanup(); // do not call it here, maybe crash your App.
#endif
#endif
}
#if defined(__TEST_WEB__)
void test_recv_data(uint8_t *data, size_t len, void *p) {
char *txt = (char *)p;
memcpy(txt, data, len);
}
int main(int argc, char *argv[]){
char txt[BUFFER_SIZE] = { 0 };
if(argc < 3){
fprintf(stderr, "Usage: %s <hostname> <port>\n", argv[0]);
exit(1);
}
launch_web_request(argv[1], atoi(argv[2]), NULL, &test_recv_data, txt);
printf("%s\n", txt);
return 0;
}
#endif // __TEST_WEB__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment