99 lines
2.7 KiB
C
99 lines
2.7 KiB
C
/**
|
|
* Copyright (c) 2026 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "network/networksocketclient.h"
|
|
#include "assert/assert.h"
|
|
#include "util/memory.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
|
|
void networkSocketClientLinuxInit(
|
|
networksocketclient_t *client,
|
|
const char_t *host,
|
|
uint16_t port,
|
|
void *user,
|
|
void (*onConnect)(void *user),
|
|
void (*onError)(errorret_t error, void *user),
|
|
void (*onDisconnect)(void *user)
|
|
) {
|
|
assertTrue(client->user == user, "Net client init mismatch?");
|
|
assertTrue(client->onConnect == onConnect, "Net client init mismatch?");
|
|
assertTrue(client->onError == onError, "Net client init mismatch?");
|
|
assertTrue(client->onDisconnect == onDisconnect, "Net client init mismatch?");
|
|
|
|
// Create the thread.
|
|
threadInit(&client->platform.thread, networkSocketClientLinuxThread);
|
|
client->platform.thread.data = client;
|
|
|
|
threadStart(&client->platform.thread);
|
|
}
|
|
|
|
void networkSocketClientLinuxThread(thread_t *thread) {
|
|
assertNotNull(thread, "Thread cannot be NULL.");
|
|
assertNotNull(thread->data, "Thread data cannot be NULL.");
|
|
|
|
networksocketclient_t *client = (networksocketclient_t *)thread->data;
|
|
|
|
// Setup socket FD
|
|
client->platform.sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
if(client->platform.sockfd < 0) {
|
|
errorret_t ret = errorThrowImpl(
|
|
&client->errorState, ERROR_NOT_OK,
|
|
__FILE__, __func__, __LINE__,
|
|
"Failed to create socket."
|
|
);
|
|
client->onError(ret, client->user);
|
|
return;
|
|
}
|
|
|
|
// Configure server address.
|
|
char_t *host = "google.com";
|
|
int port = 443;
|
|
|
|
struct sockaddr_in serverAddr;
|
|
serverAddr.sin_family = AF_INET;
|
|
serverAddr.sin_port = htons(port);
|
|
struct hostent *server = gethostbyname(host);
|
|
if(server == NULL) {
|
|
errorret_t ret = errorThrowImpl(
|
|
&client->errorState, ERROR_NOT_OK,
|
|
__FILE__, __func__, __LINE__,
|
|
"Failed to resolve host."
|
|
);
|
|
client->onError(ret, client->user);
|
|
return;
|
|
}
|
|
|
|
memoryCopy(&serverAddr.sin_addr.s_addr, server->h_addr, server->h_length);
|
|
|
|
// Connect to server.
|
|
if(connect(
|
|
client->platform.sockfd,
|
|
(struct sockaddr *)&serverAddr,
|
|
sizeof(serverAddr)
|
|
) < 0) {
|
|
errorret_t ret = errorThrowImpl(
|
|
&client->errorState, ERROR_NOT_OK,
|
|
__FILE__, __func__, __LINE__,
|
|
"Failed to connect to server."
|
|
);
|
|
client->onError(ret, client->user);
|
|
return;
|
|
}
|
|
|
|
// At this point we are connected.
|
|
client->onConnect(client->user);
|
|
|
|
// Hangup for now.
|
|
close(client->platform.sockfd);
|
|
client->onDisconnect(client->user);
|
|
} |