udp implementation
This commit is contained in:
parent
9d2f5ddc2a
commit
59b3772d5a
@ -1,5 +1,4 @@
|
||||
#include "network.h"
|
||||
#include "socket_impl_includes.h"
|
||||
#include "network_internal.h"
|
||||
|
||||
Maybe kn_tryInit(){
|
||||
#if _WIN32
|
||||
|
||||
@ -14,15 +14,6 @@ extern "C" {
|
||||
Maybe kn_tryInit();
|
||||
Maybe kt_tryDispose();
|
||||
|
||||
|
||||
|
||||
/* INTERNAL */
|
||||
|
||||
/// shutdown TCP/UDP/other std socket
|
||||
Maybe __kn_StdSocket_shutdown(i64 socketfd, knShutdownType direction);
|
||||
/// close TCP/UDP/other std socket
|
||||
Maybe __kn_StdSocket_close(i64 socketfd);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
32
src/Network/network_internal.h
Normal file
32
src/Network/network_internal.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "network.h"
|
||||
#include "socket_impl_includes.h"
|
||||
|
||||
/// shutdown TCP/UDP/other std socket
|
||||
Maybe __kn_StdSocket_shutdown(i64 socketfd, knShutdownType direction);
|
||||
|
||||
/// close TCP/UDP/other std socket
|
||||
Maybe __kn_StdSocket_close(i64 socketfd);
|
||||
|
||||
static inline struct sockaddr_in knIPV4Endpoint_toSockaddr(knIPV4Endpoint end){
|
||||
struct sockaddr_in saddr = {0};
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_addr.s_addr = end.address.UintBigEndian;
|
||||
saddr.sin_port = htons(end.port); /* transforms port number to big endian (network order) */
|
||||
return saddr;
|
||||
}
|
||||
|
||||
static inline knIPV4Endpoint knIPV4Endpoint_fromSockaddr(struct sockaddr_in saddr_ptr){
|
||||
knIPV4Address ipv4 = knIPV4Address_fromU32(saddr_ptr.sin_addr.s_addr);
|
||||
u16 port = ntohs(saddr_ptr.sin_port); /* transforms port number to little endian (normal order) */
|
||||
return knIPV4Endpoint_create(ipv4, port);
|
||||
}
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -1,45 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../base/base.h"
|
||||
|
||||
|
||||
typedef u16 knPort;
|
||||
|
||||
typedef union knIPV4Address {
|
||||
u32 UintBigEndian;
|
||||
char bytes[4];
|
||||
} knIPV4Address;
|
||||
ktid_declare(knIPV4Address);
|
||||
|
||||
#define knIPV4Address_fromBytes(A, B, C, D) ((knIPV4Address){.bytes={A,B,C,D}})
|
||||
#define knIPV4Address_fromU32(N) ((knIPV4Address){.UintBigEndian=N})
|
||||
|
||||
///@return Maybe<knIPV4Address> as Maybe<knIPV4Address>
|
||||
Maybe knIPV4Address_fromStr(char* addrStr);
|
||||
|
||||
#define IPV4_NONE knIPV4Address_fromBytes(255,255,255,255)
|
||||
#define IPV4_ANY knIPV4Address_fromBytes(0,0,0,0)
|
||||
#define IPV4_LOOPBACK knIPV4Address_fromBytes(127,0,0,1)
|
||||
|
||||
|
||||
typedef struct knIPV4Endpoint {
|
||||
knIPV4Address address;
|
||||
knPort port;
|
||||
} knIPV4Endpoint;
|
||||
ktid_declare(knIPV4Endpoint);
|
||||
|
||||
#define knIPV4Endpoint_create(ADDR, PORT) ((knIPV4Endpoint){ADDR, PORT})
|
||||
|
||||
typedef enum knShutdownType {
|
||||
knShutdownType_Receive = 0,
|
||||
knShutdownType_Send = 1,
|
||||
knShutdownType_Both = 2,
|
||||
} knShutdownType;
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../base/base.h"
|
||||
|
||||
|
||||
typedef u16 knPort;
|
||||
|
||||
typedef union knIPV4Address {
|
||||
u32 UintBigEndian;
|
||||
char bytes[4];
|
||||
} knIPV4Address;
|
||||
ktid_declare(knIPV4Address);
|
||||
|
||||
#define knIPV4Address_fromBytes(A, B, C, D) ((knIPV4Address){.bytes={A,B,C,D}})
|
||||
#define knIPV4Address_fromU32(N) ((knIPV4Address){.UintBigEndian=N})
|
||||
|
||||
///@return Maybe<knIPV4Address> as Maybe<knIPV4Address>
|
||||
Maybe knIPV4Address_fromStr(char* addrStr);
|
||||
|
||||
#define knIPV4Address_INVALID knIPV4Address_fromBytes(255,255,255,255)
|
||||
#define knIPV4Address_ANY knIPV4Address_fromBytes(0,0,0,0)
|
||||
#define knIPV4Address_LOOPBACK knIPV4Address_fromBytes(127,0,0,1)
|
||||
|
||||
|
||||
typedef struct knIPV4Endpoint {
|
||||
knIPV4Address address;
|
||||
knPort port;
|
||||
} knIPV4Endpoint;
|
||||
ktid_declare(knIPV4Endpoint);
|
||||
|
||||
#define knIPV4Endpoint_create(ADDR, PORT) ((knIPV4Endpoint){ADDR, PORT})
|
||||
|
||||
#define knIPV4Endpoint_INVALID knIPV4Endpoint_create(knIPV4Address_INVALID, ~0)
|
||||
|
||||
typedef enum knShutdownType {
|
||||
knShutdownType_Receive = 0,
|
||||
knShutdownType_Send = 1,
|
||||
knShutdownType_Both = 2,
|
||||
} knShutdownType;
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -1,5 +1,4 @@
|
||||
#include "../network.h"
|
||||
#include "../socket_impl_includes.h"
|
||||
#include "../network_internal.h"
|
||||
|
||||
ktid_define(knPackage);
|
||||
ktid_define(knPackageQueueElem);
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
#include "../network.h"
|
||||
#include "../socket_impl_includes.h"
|
||||
#include "../network_internal.h"
|
||||
|
||||
ktid_define(knSocketTCP);
|
||||
|
||||
Maybe knSocketTCP_open(bool allowReuse){
|
||||
knSocketTCP* newSocket=malloc(sizeof(knSocketTCP));
|
||||
newSocket->localEndpoint=knIPV4Endpoint_create(IPV4_NONE,0);
|
||||
newSocket->remoteEndpoint=knIPV4Endpoint_create(IPV4_NONE,0);
|
||||
newSocket->localEndpoint=knIPV4Endpoint_INVALID;
|
||||
newSocket->remoteEndpoint=knIPV4Endpoint_INVALID;
|
||||
newSocket->socketfd=socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(newSocket->socketfd==-1 || newSocket->socketfd == ~0)
|
||||
safethrow("can't create socket", free(newSocket));
|
||||
@ -29,39 +29,37 @@ Maybe knSocketTCP_close(knSocketTCP* socket){
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_listen(knSocketTCP* socket, knIPV4Endpoint localEndp){
|
||||
struct sockaddr_in servaddr;
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = localEndp.address.UintBigEndian;
|
||||
servaddr.sin_port = htons(localEndp.port);
|
||||
int r = bind(socket->socketfd,(struct sockaddr*)&servaddr, sizeof(servaddr));
|
||||
if(r != 0)
|
||||
safethrow("socket bind failed",;);
|
||||
socket->localEndpoint=localEndp;
|
||||
Maybe knSocketTCP_bindAndListen(knSocketTCP* socket, knIPV4Endpoint localEndp){
|
||||
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(localEndp);
|
||||
|
||||
if(bind(socket->socketfd, (void*)&servaddr, sizeof(servaddr)) != 0)
|
||||
safethrow("socket bind failed", ;);
|
||||
|
||||
r = listen(socket->socketfd, 1024);
|
||||
if(r != 0)
|
||||
safethrow("socket listen failed",;);
|
||||
if(listen(socket->socketfd, 1024) != 0)
|
||||
safethrow("socket listen failed", ;);
|
||||
|
||||
socket->localEndpoint = localEndp;
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEndp){
|
||||
struct sockaddr_in servaddr;
|
||||
servaddr.sin_family=AF_INET;
|
||||
servaddr.sin_addr.s_addr = remoteEndp.address.UintBigEndian;
|
||||
servaddr.sin_port = htons(remoteEndp.port);
|
||||
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd){
|
||||
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(remoteEnd);
|
||||
|
||||
if(connect(socket->socketfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) !=0)
|
||||
safethrow("socket connect failed",;);
|
||||
socket->remoteEndpoint=remoteEndp;
|
||||
|
||||
socket->remoteEndpoint=remoteEnd;
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_accept(knSocketTCP* socket){
|
||||
struct sockaddr_in remoteAddr = {0};
|
||||
u64 remoteAddrSize = sizeof(remoteAddr);
|
||||
|
||||
i64 client_fd = accept(socket->socketfd, (struct sockaddr*)&remoteAddr, (void*)&remoteAddrSize);
|
||||
if(client_fd == -1 || client_fd == ~0)
|
||||
safethrow("can't accept client connection", ;);
|
||||
|
||||
// if accept() didn't set remoteAddr for some reason
|
||||
if(remoteAddr.sin_addr.s_addr == 0 && remoteAddr.sin_port == 0 && remoteAddr.sin_family == 0){
|
||||
if(getpeername(client_fd, (struct sockaddr*)&remoteAddr, (void*)&remoteAddrSize) != 0)
|
||||
@ -71,16 +69,14 @@ Maybe knSocketTCP_accept(knSocketTCP* socket){
|
||||
knSocketTCP* clientSocket = malloc(sizeof(knSocketTCP));
|
||||
clientSocket->socketfd = client_fd;
|
||||
clientSocket->localEndpoint = socket->localEndpoint;
|
||||
clientSocket->remoteEndpoint = knIPV4Endpoint_create(
|
||||
knIPV4Address_fromU32(remoteAddr.sin_addr.s_addr),
|
||||
remoteAddr.sin_port);
|
||||
clientSocket->remoteEndpoint = knIPV4Endpoint_fromSockaddr(remoteAddr);
|
||||
return SUCCESS(UniHeapPtr(knSocketTCP, clientSocket));
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength){
|
||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength){
|
||||
u32 sentTotal = 0;
|
||||
while(sentTotal < dataLength){
|
||||
int sentCount = send(socket->socketfd, data+sentTotal, dataLength-sentTotal, 0);
|
||||
int sentCount = send(socket->socketfd, buffer+sentTotal, dataLength-sentTotal, 0);
|
||||
if(sentCount == -1){
|
||||
safethrow(
|
||||
cptr_concat("can't send ", toString_u64(dataLength-sentTotal,0,0),
|
||||
@ -91,6 +87,7 @@ Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength){
|
||||
}
|
||||
sentTotal += sentCount;
|
||||
}
|
||||
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
@ -98,5 +95,6 @@ Maybe knSocketTCP_receive(knSocketTCP* socket, char* buffer, u32 bufferLength){
|
||||
int receivedCount = recv(socket->socketfd, buffer, bufferLength, 0);
|
||||
if(receivedCount == -1 || receivedCount == 0)
|
||||
safethrow("can't receive data from socket", ;)
|
||||
|
||||
return SUCCESS(UniUInt64(receivedCount));
|
||||
}
|
||||
|
||||
@ -28,21 +28,25 @@ Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction);
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_close(knSocketTCP* socket);
|
||||
|
||||
///start listening at local endpoint
|
||||
/// binds socket to a local endpoint and starts listening for incoming TCP connections
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_listen(knSocketTCP* socket, knIPV4Endpoint localEndp);
|
||||
Maybe knSocketTCP_bindAndListen(knSocketTCP* socket, knIPV4Endpoint localEndp);
|
||||
|
||||
///sets socket remote endpoint
|
||||
/// establishes TCP connection with a remote endpoint
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEndp);
|
||||
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd);
|
||||
|
||||
///@return Maybe<knSocketTCP*> new socket connected to client
|
||||
Maybe knSocketTCP_accept(knSocketTCP* socket);
|
||||
|
||||
/// sends <dataLength> bytes from buffer
|
||||
///@param buffer buffer for receiving data
|
||||
///@param dataLength 0-4294967295
|
||||
///@return Maybe<void>
|
||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength);
|
||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength);
|
||||
|
||||
/// receives a package of any size
|
||||
/// (by TCP 32 bytes han be sent as 32x1byte, 4x8byte, 32x1byte or in any other combination)
|
||||
///@param buffer buffer for receiving data
|
||||
///@param bufferLength 0-4294967295
|
||||
///@return Maybe<u64> received bytes amount
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "../network.h"
|
||||
#include "../socket_impl_includes.h"
|
||||
#include "../network_internal.h"
|
||||
|
||||
ktid_define(knSocketUDP);
|
||||
|
||||
Maybe knSocketUDP_open(bool allowReuse){
|
||||
@ -28,10 +28,57 @@ Maybe knSocketUDP_close(knSocketUDP* socket){
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_listen(knSocketUDP* socket, knIPV4Endpoint localEndp);
|
||||
Maybe knSocketUDP_bind(knSocketUDP* socket, knIPV4Endpoint localEndp){
|
||||
struct sockaddr_in servaddr = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = localEndp.address.UintBigEndian,
|
||||
.sin_port = htons(localEndp.port) /* transforms port to big endian */
|
||||
};
|
||||
|
||||
if(bind(socket->socketfd, (void*)&servaddr, sizeof(servaddr)) != 0)
|
||||
safethrow("socket bind failed", ;);
|
||||
|
||||
Maybe knSocketUDP_accept(knSocketUDP* socket);
|
||||
socket->localEndpoint = localEndp;
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, u32 dataLength, knIPV4Endpoint destination);
|
||||
Maybe knSocketUDP_sendTo(knSocketUDP* socket, char* buffer, u32 dataLength, knIPV4Endpoint destEnd){
|
||||
struct sockaddr_in dest_saddr = knIPV4Endpoint_toSockaddr(destEnd);
|
||||
u32 sentCount = sendto(
|
||||
socket->socketfd,
|
||||
buffer,
|
||||
dataLength,
|
||||
0,
|
||||
(struct sockaddr*)&dest_saddr,
|
||||
sizeof(struct sockaddr_in)
|
||||
);
|
||||
|
||||
if(sentCount != dataLength) {
|
||||
safethrow(
|
||||
cptr_concat("can't send ", toString_u64(dataLength-sentCount,0,0),
|
||||
" bytes out of ", toString_u64(dataLength,0,0)
|
||||
),
|
||||
;);
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_receive(knSocketUDP* socket, char* buffer, u32 bufferLength);
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_receiveAny(knSocketUDP* socket, char* buffer, u32 bufferLength, knIPV4Endpoint* senderEnd){
|
||||
struct sockaddr_in remote_saddr = {0};
|
||||
u64 remote_saddr_size = sizeof(remote_saddr);
|
||||
int receivedCount = recvfrom(
|
||||
socket->socketfd,
|
||||
buffer,
|
||||
bufferLength,
|
||||
0,
|
||||
(struct sockaddr*)&remote_saddr,
|
||||
(void*)&remote_saddr_size
|
||||
);
|
||||
|
||||
if(receivedCount == -1 || receivedCount == 0)
|
||||
safethrow("can't receive data from socket", ;)
|
||||
|
||||
*senderEnd = knIPV4Endpoint_fromSockaddr(remote_saddr);
|
||||
return SUCCESS(UniUInt64(receivedCount));
|
||||
}
|
||||
|
||||
@ -27,22 +27,23 @@ Maybe knSocketUDP_shutdown(knSocketUDP* socket, knShutdownType direction);
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketUDP_close(knSocketUDP* socket);
|
||||
|
||||
///start listening at local endpoint
|
||||
/// binds socket to a local endpoint
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketUDP_listen(knSocketUDP* socket, knIPV4Endpoint localEndp);
|
||||
|
||||
///@return Maybe<knSocketUDP*> new socket connected to client
|
||||
Maybe knSocketUDP_accept(knSocketUDP* socket);
|
||||
|
||||
///@param dataLength 0-4294967295
|
||||
///@return Maybe<void>
|
||||
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, u32 dataLength, knIPV4Endpoint destination);
|
||||
Maybe knSocketUDP_bind(knSocketUDP* socket, knIPV4Endpoint localEndp);
|
||||
|
||||
/// sends one package to destination endpoint
|
||||
///@param buffer buffer for receiving data
|
||||
///@param bufferLength 0-4294967295
|
||||
///@return Maybe<u64> received bytes amount
|
||||
Maybe knSocketUDP_receive(knSocketUDP* socket, char* buffer, u32 bufferLength);
|
||||
///@param dataLength 0-64k
|
||||
///@param destEnd destination endpoint
|
||||
///@return Maybe<void>
|
||||
Maybe knSocketUDP_sendTo(knSocketUDP* socket, char* buffer, u32 dataLength, knIPV4Endpoint destEnd);
|
||||
|
||||
/// receives one package from anywhere
|
||||
///@param buffer buffer for receiving data
|
||||
///@param bufferLength 0-64k
|
||||
///@param senderEnd [OUT] endpoint UPD package was sent from
|
||||
///@return Maybe<u64> received bytes amount
|
||||
Maybe knSocketUDP_receiveAny(knSocketUDP* socket, char* buffer, u32 bufferLength, knIPV4Endpoint* senderEnd);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ void* tcp_client_connect_async(void* _data){
|
||||
|
||||
static void test_tcp(){
|
||||
kprintf("\e[96m----------[test_network/tcp]----------\n");
|
||||
knIPV4Endpoint serverEnd = knIPV4Endpoint_create(IPV4_LOOPBACK, 4444);
|
||||
knIPV4Endpoint serverEnd = knIPV4Endpoint_create(knIPV4Address_LOOPBACK, 4444);
|
||||
knSocketTCP *socket_server, *clientConnection, *socket_client;
|
||||
// server
|
||||
{
|
||||
@ -65,7 +65,7 @@ static void test_tcp(){
|
||||
socket_server=m_socketS.value.VoidPtr;
|
||||
kprintf("\e[92mTCP server socket created\n");
|
||||
|
||||
tryLast(knSocketTCP_listen(socket_server, serverEnd), _m81775, ;)
|
||||
tryLast(knSocketTCP_bindAndListen(socket_server, serverEnd), _m81775, ;)
|
||||
kprintf("\e[92mserver socket is listening\n");
|
||||
}
|
||||
// client
|
||||
|
||||
Loading…
Reference in New Issue
Block a user