implemented socket send and receive

This commit is contained in:
2025-07-22 23:57:11 +03:00
parent 94091d7797
commit 7cd7535eb0
9 changed files with 129 additions and 62 deletions

View File

@@ -1,5 +1,5 @@
#include "std_includes.h"
#include "endpoint.h"
#include "network.h"
struct sockaddr_in EndpointIPv4_toSockaddr(EndpointIPv4 end){
struct sockaddr_in saddr = {0};
@@ -18,6 +18,7 @@ EndpointIPv4 EndpointIPv4_fromSockaddr(struct sockaddr_in saddr){
return end;
}
//TODO Endpoint functions
AddressIPv4 AddressIPv4_fromStr(cstr);
str AddressIPv4_toStr(AddressIPv4 address);

View File

@@ -1,7 +1,6 @@
#pragma once
#include "tlibc/std.h"
#include "tlibc/string/str.h"
#include "network.h"
#define port_INVALID ((port)~0)
#define port_is_invalid(PORT) (PORT == port_INVALID)

View File

@@ -1,5 +1,5 @@
#include "network.h"
#include "network.h"
#include "std_includes.h"
Result(void) network_init(){
#if _WIN32

View File

@@ -1,22 +1,5 @@
#pragma once
#include "tlibc/errors.h"
#if defined(_WIN64) || defined(_WIN32)
#define KN_USE_WINSOCK 1
#else
#define KN_USE_WINSOCK 0
#endif
#if KN_USE_WINSOCK
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif
Result(void) network_init();
Result(void) network_deinit();

View File

@@ -1,14 +1,15 @@
#include "network.h"
#include "network.h"
#include "std_includes.h"
#include "socket.h"
#include "errno.h"
#include "assert.h"
Result(Socket) socket_open_TCP(){
Socket s = socket(AF_INET, SOCK_STREAM, 0);
if(s == -1){
return RESULT_ERROR("can't create socket", false);
return RESULT_ERROR(strerror(errno), false);
}
return RESULT_VALUE(i64, s);
return RESULT_VALUE(i, s);
}
void socket_close(Socket s){
@@ -21,33 +22,79 @@ void socket_close(Socket s){
Result(void) socket_shutdown(Socket s, SocketShutdownType direction){
if(shutdown(s, (int)direction) == -1)
return RESULT_ERROR("shutdown() failed", false);
return RESULT_ERROR(strerror(errno), false);
return RESULT_VOID;
}
Result(void) socket_bind(Socket s, EndpointIPv4 local_end){
struct sockaddr_in sockaddr = EndpointIPv4_toSockaddr(local_end);
if(bind(s, (void*)&sockaddr, sizeof(sockaddr)) != 0)
return RESULT_ERROR("bind() failed", false);
return RESULT_ERROR(strerror(errno), false);
return RESULT_VOID;
}
Result(void) socket_listen(Socket s, i32 backlog){
if(listen(s, backlog) != 0)
return RESULT_ERROR("listen() failed", false);
return RESULT_ERROR(strerror(errno), false);
return RESULT_VOID;
}
Result(Socket) socket_accept(Socket main_socket) {
Result(Socket) socket_accept(Socket main_socket, NULLABLE(EndpointIPv4*) remote_end) {
struct sockaddr_in remote_addr = {0};
i32 sockaddr_size = sizeof(remote_addr);
Socket user_connection = accept(main_socket, (struct sockaddr*)&remote_addr, (void*)&sockaddr_size);
return RESULT_VALUE(i64, user_connection);
Socket user_connection = accept(main_socket, (void*)&remote_addr, (void*)&sockaddr_size);
if(user_connection == -1)
return RESULT_ERROR(strerror(errno), false);
//TODO: add IPV6 support (struct sockaddr_in6)
assert(sockaddr_size == sizeof(remote_addr));
if(remote_end)
*remote_end = EndpointIPv4_fromSockaddr(remote_addr);
return RESULT_VALUE(i, user_connection);
}
Result(void) socket_connect(Socket s, EndpointIPv4 remote_end){
struct sockaddr_in sockaddr = EndpointIPv4_toSockaddr(remote_end);
if(connect(s, (void*)&sockaddr, sizeof(sockaddr)) != 0)
return RESULT_ERROR("connect() failed", false);
return RESULT_ERROR(strerror(errno), false);
return RESULT_VOID;
}
Result(void) socket_send(Socket s, Array buffer){
i32 r = send(s, buffer.data, buffer.size, 0);
if(r < 0)
return RESULT_ERROR(strerror(errno), false);
return RESULT_VOID;
}
Result(void) socket_sendto(Socket s, Array buffer, EndpointIPv4 dst){
struct sockaddr_in sockaddr = EndpointIPv4_toSockaddr(dst);
i32 r = sendto(s, buffer.data, buffer.size, 0, (void*)&sockaddr, sizeof(sockaddr));
if(r < 0)
return RESULT_ERROR(strerror(errno), false);
return RESULT_VOID;
}
Result(i32) socket_recv(Socket s, Array buffer){
i32 r = recv(s, buffer.data, buffer.size, 0);
if(r < 0)
return RESULT_ERROR(strerror(errno), false);
return RESULT_VALUE(i, r);
}
Result(i32) socket_recvfrom(Socket s, Array buffer, NULLABLE(EndpointIPv4*) remote_end){
struct sockaddr_in remote_addr = {0};
i32 sockaddr_size = sizeof(remote_addr);
i32 r = recvfrom(s, buffer.data, buffer.size, 0,
(struct sockaddr*)&remote_addr, (void*)&sockaddr_size);
if(r < 0)
return RESULT_ERROR(strerror(errno), false);
//TODO: add IPV6 support (struct sockaddr_in6)
assert(sockaddr_size == sizeof(remote_addr));
if(remote_end)
*remote_end = EndpointIPv4_fromSockaddr(remote_addr);
return RESULT_VALUE(i, r);
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "endpoint.h"
#include "tlibc/errors.h"
#include "tlibc/collections/Array.h"
typedef enum SocketShutdownType {
SocketShutdownType_Receive = 0,
@@ -10,10 +11,14 @@ typedef enum SocketShutdownType {
typedef i64 Socket;
Result(Socket) socket_open_TCP();
void socket_close(Socket s);
Result(void) socket_shutdown(Socket s, SocketShutdownType direction);
Result(void) socket_bind(Socket s, EndpointIPv4 local_end);
Result(void) socket_listen(Socket s, i32 backlog);
Result(Socket) socket_accept(Socket s);
Result(void) socket_connect(Socket s, EndpointIPv4 remote_end);
Result(Socket) socket_open_TCP();
void socket_close(Socket s);
Result(void) socket_shutdown(Socket s, SocketShutdownType direction);
Result(void) socket_bind(Socket s, EndpointIPv4 local_end);
Result(void) socket_listen(Socket s, i32 backlog);
Result(Socket) socket_accept(Socket s, NULLABLE(EndpointIPv4*) remote_end);
Result(void) socket_connect(Socket s, EndpointIPv4 remote_end);
Result(void) socket_send(Socket s, Array buffer);
Result(void) socket_sendto(Socket s, Array buffer, EndpointIPv4 dst);
Result(i32) socket_recv(Socket s, Array buffer);
Result(i32) socket_recvfrom(Socket s, Array buffer, NULLABLE(EndpointIPv4*) remote_end);

View File

@@ -0,0 +1,18 @@
#pragma once
#if defined(_WIN64) || defined(_WIN32)
#define KN_USE_WINSOCK 1
#else
#define KN_USE_WINSOCK 0
#endif
#if KN_USE_WINSOCK
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif