some fixes in sockets and complete tcp client/server test
This commit is contained in:
@@ -28,7 +28,7 @@ Maybe kt_tryDispose(){
|
||||
|
||||
|
||||
Maybe __kn_StdSocket_shutdown(i64 socketfd, knShutdownType direction){
|
||||
if(shutdown(socketfd, SD_SEND) == -1)
|
||||
if(shutdown(socketfd, (int)direction) == -1)
|
||||
safethrow("can't shutdown socket", ;);
|
||||
return MaybeNull;
|
||||
}
|
||||
@@ -37,7 +37,7 @@ Maybe __kn_StdSocket_close(i64 socketfd){
|
||||
#if KN_USE_WINSOCK
|
||||
if(closesocket(socketfd) == -1)
|
||||
#else
|
||||
if(close(socket->socketfd) == -1)
|
||||
if(close(socketfd) == -1)
|
||||
#endif
|
||||
safethrow("can't close socket", ;);
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../base/base.h"
|
||||
|
||||
#include "network_types.h"
|
||||
#include "sockets/knSocketTCP.h"
|
||||
#include "sockets/knSocketUDP.h"
|
||||
#include "sockets/knSocketChanneled.h"
|
||||
|
||||
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
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../base/base.h"
|
||||
|
||||
#include "network_types.h"
|
||||
#include "sockets/knSocketTCP.h"
|
||||
#include "sockets/knSocketUDP.h"
|
||||
#include "sockets/knSocketChanneled.h"
|
||||
|
||||
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
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
#include "../network.h"
|
||||
#include "../socket_impl_includes.h"
|
||||
|
||||
ktid_define(knPackage);
|
||||
ktid_define(knPackageQueueElem);
|
||||
ktid_define(knChannel);
|
||||
ktid_define(knSocketChanneled);
|
||||
|
||||
Maybe knSocketChanneled_open(){
|
||||
knSocketChanneled* newSocket=malloc(sizeof(knSocketChanneled));
|
||||
newSocket->localEndpoint=knIPV4Endpoint_create(knIPV4Address_fromBytes(0,0,0,0),0);
|
||||
newSocket->remoteEndpoint=newSocket->localEndpoint;
|
||||
newSocket->channels=NULL;
|
||||
newSocket->channelsAmount=0;
|
||||
return SUCCESS(UniHeapPtr(knSocketChanneled, newSocket));
|
||||
}
|
||||
|
||||
Maybe knSocketChanneled_close(knSocketChanneled* socket){
|
||||
int result=
|
||||
#if KN_USE_WINSOCK
|
||||
closesocket
|
||||
#else
|
||||
close
|
||||
#endif
|
||||
(socket->socketfd);
|
||||
if(result==-1) {
|
||||
safethrow("can't close socket",;);
|
||||
}
|
||||
else return MaybeNull;
|
||||
}
|
||||
|
||||
knChannel* __createChannel(){
|
||||
knChannel* ch=malloc(sizeof(knChannel));
|
||||
ch->queueStart=NULL;
|
||||
return ch;
|
||||
}
|
||||
|
||||
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket){
|
||||
if(socket->channelsAmount == 65535)
|
||||
safethrow("max amount of channels",;);
|
||||
u16 channelsAmountPrev=socket->channelsAmount;
|
||||
socket->channelsAmount++;
|
||||
if(channelsAmountPrev==0)
|
||||
socket->channels=malloc(sizeof(knChannel*));
|
||||
else
|
||||
socket->channels=realloc(socket->channels, socket->channelsAmount*sizeof(knChannel*));
|
||||
socket->channels[channelsAmountPrev]=__createChannel();
|
||||
return SUCCESS(UniUInt64(channelsAmountPrev));
|
||||
}
|
||||
|
||||
Maybe knSocketChanneled_listen(knSocketChanneled* socket, knIPV4Endpoint localEndp);
|
||||
|
||||
Maybe knSocketChanneled_connect(knSocketChanneled* socket, knIPV4Endpoint remoteEndp);
|
||||
|
||||
Maybe knSocketChanneled_accept(knSocketChanneled* socket);
|
||||
|
||||
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
|
||||
|
||||
#include "../network.h"
|
||||
#include "../socket_impl_includes.h"
|
||||
|
||||
ktid_define(knPackage);
|
||||
ktid_define(knPackageQueueElem);
|
||||
ktid_define(knChannel);
|
||||
ktid_define(knSocketChanneled);
|
||||
|
||||
Maybe knSocketChanneled_open(){
|
||||
knSocketChanneled* newSocket=malloc(sizeof(knSocketChanneled));
|
||||
newSocket->localEndpoint=knIPV4Endpoint_create(knIPV4Address_fromBytes(0,0,0,0),0);
|
||||
newSocket->remoteEndpoint=newSocket->localEndpoint;
|
||||
newSocket->channels=NULL;
|
||||
newSocket->channelsAmount=0;
|
||||
return SUCCESS(UniHeapPtr(knSocketChanneled, newSocket));
|
||||
}
|
||||
|
||||
Maybe knSocketChanneled_close(knSocketChanneled* socket){
|
||||
int result=
|
||||
#if KN_USE_WINSOCK
|
||||
closesocket
|
||||
#else
|
||||
close
|
||||
#endif
|
||||
(socket->socketfd);
|
||||
if(result==-1) {
|
||||
safethrow("can't close socket",;);
|
||||
}
|
||||
else return MaybeNull;
|
||||
}
|
||||
|
||||
knChannel* __createChannel(){
|
||||
knChannel* ch=malloc(sizeof(knChannel));
|
||||
ch->queueStart=NULL;
|
||||
return ch;
|
||||
}
|
||||
|
||||
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket){
|
||||
if(socket->channelsAmount == 65535)
|
||||
safethrow("max amount of channels",;);
|
||||
u16 channelsAmountPrev=socket->channelsAmount;
|
||||
socket->channelsAmount++;
|
||||
if(channelsAmountPrev==0)
|
||||
socket->channels=malloc(sizeof(knChannel*));
|
||||
else
|
||||
socket->channels=realloc(socket->channels, socket->channelsAmount*sizeof(knChannel*));
|
||||
socket->channels[channelsAmountPrev]=__createChannel();
|
||||
return SUCCESS(UniUInt64(channelsAmountPrev));
|
||||
}
|
||||
|
||||
Maybe knSocketChanneled_listen(knSocketChanneled* socket, knIPV4Endpoint localEndp);
|
||||
|
||||
Maybe knSocketChanneled_connect(knSocketChanneled* socket, knIPV4Endpoint remoteEndp);
|
||||
|
||||
Maybe knSocketChanneled_accept(knSocketChanneled* socket);
|
||||
|
||||
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
|
||||
|
||||
Maybe knSocketChanneled_receive(knSocketChanneled* socket, u16 destinationIndex, u8* buffer, u32 bufferLength);
|
||||
@@ -1,97 +1,102 @@
|
||||
#include "../network.h"
|
||||
#include "../socket_impl_includes.h"
|
||||
ktid_define(knSocketTCP);
|
||||
|
||||
Maybe knSocketTCP_open(){
|
||||
knSocketTCP* newSocket=malloc(sizeof(knSocketTCP));
|
||||
newSocket->localEndpoint=knIPV4Endpoint_create(IPV4_NONE,0);
|
||||
newSocket->remoteEndpoint=newSocket->localEndpoint;
|
||||
newSocket->socketfd=socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(newSocket->socketfd==-1 || newSocket->socketfd == ~0)
|
||||
safethrow("can't create TCP socket", free(newSocket));
|
||||
|
||||
return SUCCESS(UniHeapPtr(knSocketTCP, newSocket));
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction){
|
||||
try(__kn_StdSocket_shutdown(socket->socketfd, direction), _m875, ;);
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_close(knSocketTCP* socket){
|
||||
try(__kn_StdSocket_close(socket->socketfd), _m875, ;);
|
||||
socket->socketfd = 0;
|
||||
socket->localEndpoint = knIPV4Endpoint_create(IPV4_NONE, -1);
|
||||
socket->remoteEndpoint = knIPV4Endpoint_create(IPV4_NONE, -1);
|
||||
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);
|
||||
if(bind(socket->socketfd,(struct sockaddr*)&servaddr, sizeof(servaddr)) !=0)
|
||||
safethrow("socket bind failed",;);
|
||||
socket->localEndpoint=localEndp;
|
||||
if(listen(socket->socketfd, 256) !=0)
|
||||
safethrow("socket listen failed",;);
|
||||
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);
|
||||
if(connect(socket->socketfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) !=0)
|
||||
safethrow("socket connect failed",;);
|
||||
socket->remoteEndpoint=remoteEndp;
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_accept(knSocketTCP* socket){
|
||||
struct sockaddr_in remoteAddr = {0};
|
||||
int remoteAddrSize = sizeof(remoteAddr);
|
||||
i64 client_fd = accept(socket->socketfd, (struct sockaddr*)&remoteAddr, &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, &remoteAddrSize) != 0)
|
||||
safethrow("can't get connected client address", ;);
|
||||
}
|
||||
|
||||
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);
|
||||
return SUCCESS(UniHeapPtr(knSocketTCP, clientSocket));
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength){
|
||||
u32 sentTotal = 0;
|
||||
while(sentTotal < dataLength){
|
||||
int sentCount = send(socket->socketfd, data+sentTotal, dataLength-sentTotal, 0);
|
||||
if(sentCount == -1){
|
||||
safethrow(
|
||||
cptr_concat("can't send ", toString_u64(dataLength-sentTotal,0,0),
|
||||
" bytes out of ", toString_u64(dataLength,0,0),
|
||||
" at index ", toString_u64(sentTotal,0,0),
|
||||
" to TCP socket"
|
||||
),
|
||||
;);
|
||||
}
|
||||
sentTotal += sentCount;
|
||||
}
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
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 TCP socket", ;)
|
||||
return SUCCESS(UniUInt64(receivedCount));
|
||||
}
|
||||
#include "../network.h"
|
||||
#include "../socket_impl_includes.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->socketfd=socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(newSocket->socketfd==-1 || newSocket->socketfd == ~0)
|
||||
safethrow("can't create socket", free(newSocket));
|
||||
|
||||
// set value of REUSEADDR socket option
|
||||
int opt_val = allowReuse;
|
||||
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
|
||||
safethrow("can't set socket options", free(newSocket));
|
||||
|
||||
return SUCCESS(UniHeapPtr(knSocketTCP, newSocket));
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction){
|
||||
try(__kn_StdSocket_shutdown(socket->socketfd, direction), _m875, ;);
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_close(knSocketTCP* socket){
|
||||
try(__kn_StdSocket_close(socket->socketfd), _m875, ;);
|
||||
free(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;
|
||||
|
||||
r = listen(socket->socketfd, 1024);
|
||||
if(r != 0)
|
||||
safethrow("socket listen failed",;);
|
||||
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);
|
||||
if(connect(socket->socketfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) !=0)
|
||||
safethrow("socket connect failed",;);
|
||||
socket->remoteEndpoint=remoteEndp;
|
||||
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)
|
||||
safethrow("can't get connected client address", ;);
|
||||
}
|
||||
|
||||
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);
|
||||
return SUCCESS(UniHeapPtr(knSocketTCP, clientSocket));
|
||||
}
|
||||
|
||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength){
|
||||
u32 sentTotal = 0;
|
||||
while(sentTotal < dataLength){
|
||||
int sentCount = send(socket->socketfd, data+sentTotal, dataLength-sentTotal, 0);
|
||||
if(sentCount == -1){
|
||||
safethrow(
|
||||
cptr_concat("can't send ", toString_u64(dataLength-sentTotal,0,0),
|
||||
" bytes out of ", toString_u64(dataLength,0,0),
|
||||
" at index ", toString_u64(sentTotal,0,0)
|
||||
),
|
||||
;);
|
||||
}
|
||||
sentTotal += sentCount;
|
||||
}
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -1,49 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../network_types.h"
|
||||
|
||||
typedef struct knSocketTCP {
|
||||
i64 socketfd;
|
||||
knIPV4Endpoint localEndpoint;
|
||||
knIPV4Endpoint remoteEndpoint;
|
||||
// TODO socket status enum
|
||||
} knSocketTCP;
|
||||
ktid_declare(knSocketTCP);
|
||||
|
||||
///@return Maybe<knSocketTCP*> new socket
|
||||
Maybe knSocketTCP_open();
|
||||
|
||||
///@param direction receive/send/both
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction);
|
||||
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_close(knSocketTCP* socket);
|
||||
|
||||
///start listening at local endpoint
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_listen(knSocketTCP* socket, knIPV4Endpoint localEndp);
|
||||
|
||||
///sets socket remote endpoint
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEndp);
|
||||
|
||||
///@return Maybe<knSocketTCP*> new socket connected to client
|
||||
Maybe knSocketTCP_accept(knSocketTCP* socket);
|
||||
|
||||
///@param dataLength 0-4294967295
|
||||
///@return Maybe<void>
|
||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength);
|
||||
|
||||
///@param buffer buffer for receiving data
|
||||
///@param bufferLength 0-4294967295
|
||||
///@return Maybe<u64> received bytes amount
|
||||
Maybe knSocketTCP_receive(knSocketTCP* socket, char* buffer, u32 bufferLength);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../network_types.h"
|
||||
|
||||
typedef struct knSocketTCP {
|
||||
i64 socketfd;
|
||||
knIPV4Endpoint localEndpoint;
|
||||
knIPV4Endpoint remoteEndpoint;
|
||||
// TODO socket status enum
|
||||
} knSocketTCP;
|
||||
ktid_declare(knSocketTCP);
|
||||
|
||||
///@note EXAMPLE 1: socket = open(false); bind(socket, localhost:8080); close(socket); - the socket on port 8080 still unavaliable for several minutes
|
||||
///@note EXAMPLE 2: socket = open(true); bind(socket, localhost:8080); close(socket); - the socket on port 8080 can be opened again
|
||||
///@param allowReuse enables binding multiple sockets to single port. Set to TRUE on a listening socket if you want to bind it to the same port after close.
|
||||
///@return Maybe<knSocketTCP*> new socket
|
||||
Maybe knSocketTCP_open(bool allowReuse);
|
||||
|
||||
///@param direction receive/send/both
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction);
|
||||
|
||||
/// closes file descriptor and frees socket pointer
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_close(knSocketTCP* socket);
|
||||
|
||||
///start listening at local endpoint
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_listen(knSocketTCP* socket, knIPV4Endpoint localEndp);
|
||||
|
||||
///sets socket remote endpoint
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEndp);
|
||||
|
||||
///@return Maybe<knSocketTCP*> new socket connected to client
|
||||
Maybe knSocketTCP_accept(knSocketTCP* socket);
|
||||
|
||||
///@param dataLength 0-4294967295
|
||||
///@return Maybe<void>
|
||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength);
|
||||
|
||||
///@param buffer buffer for receiving data
|
||||
///@param bufferLength 0-4294967295
|
||||
///@return Maybe<u64> received bytes amount
|
||||
Maybe knSocketTCP_receive(knSocketTCP* socket, char* buffer, u32 bufferLength);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,33 +1,37 @@
|
||||
#include "../network.h"
|
||||
#include "../socket_impl_includes.h"
|
||||
ktid_define(knSocketUDP);
|
||||
|
||||
Maybe knSocketUDP_open(){
|
||||
knSocketUDP* newSocket=malloc(sizeof(knSocketUDP));
|
||||
newSocket->localEndpoint=knIPV4Endpoint_create(knIPV4Address_fromBytes(0,0,0,0),0);
|
||||
newSocket->socketfd=socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(newSocket->socketfd==-1)
|
||||
safethrow("can't create UDP socket", free(newSocket));
|
||||
|
||||
return SUCCESS(UniHeapPtr(knSocketUDP, newSocket));
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_shutdown(knSocketUDP* socket, knShutdownType direction){
|
||||
try(__kn_StdSocket_shutdown(socket->socketfd, direction), _m875, ;);
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_close(knSocketUDP* socket){
|
||||
try(__kn_StdSocket_close(socket->socketfd), _m875, ;);
|
||||
socket->socketfd = 0;
|
||||
socket->localEndpoint = knIPV4Endpoint_create(IPV4_NONE, -1);
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_listen(knSocketUDP* socket, knIPV4Endpoint localEndp);
|
||||
|
||||
Maybe knSocketUDP_accept(knSocketUDP* socket);
|
||||
|
||||
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, u32 dataLength, knIPV4Endpoint destination);
|
||||
|
||||
Maybe knSocketUDP_receive(knSocketUDP* socket, char* buffer, u32 bufferLength);
|
||||
#include "../network.h"
|
||||
#include "../socket_impl_includes.h"
|
||||
ktid_define(knSocketUDP);
|
||||
|
||||
Maybe knSocketUDP_open(bool allowReuse){
|
||||
knSocketUDP* newSocket=malloc(sizeof(knSocketUDP));
|
||||
newSocket->localEndpoint=knIPV4Endpoint_create(knIPV4Address_fromBytes(0,0,0,0),0);
|
||||
newSocket->socketfd=socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(newSocket->socketfd==-1)
|
||||
safethrow("can't create socket", free(newSocket));
|
||||
|
||||
// set value of REUSEADDR socket option
|
||||
int opt_val = allowReuse;
|
||||
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
|
||||
safethrow("can't set socket options", free(newSocket));
|
||||
|
||||
return SUCCESS(UniHeapPtr(knSocketUDP, newSocket));
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_shutdown(knSocketUDP* socket, knShutdownType direction){
|
||||
try(__kn_StdSocket_shutdown(socket->socketfd, direction), _m875, ;);
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_close(knSocketUDP* socket){
|
||||
try(__kn_StdSocket_close(socket->socketfd), _m875, ;);
|
||||
free(socket);
|
||||
return MaybeNull;
|
||||
}
|
||||
|
||||
Maybe knSocketUDP_listen(knSocketUDP* socket, knIPV4Endpoint localEndp);
|
||||
|
||||
Maybe knSocketUDP_accept(knSocketUDP* socket);
|
||||
|
||||
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, u32 dataLength, knIPV4Endpoint destination);
|
||||
|
||||
Maybe knSocketUDP_receive(knSocketUDP* socket, char* buffer, u32 bufferLength);
|
||||
|
||||
@@ -1,45 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../network_types.h"
|
||||
|
||||
typedef struct knSocketUDP {
|
||||
i64 socketfd;
|
||||
knIPV4Endpoint localEndpoint;
|
||||
// TODO socket status enum
|
||||
} knSocketUDP;
|
||||
ktid_declare(knSocketUDP);
|
||||
|
||||
///@return Maybe<knSocketUDP*> new socket
|
||||
Maybe knSocketUDP_open();
|
||||
|
||||
///@param direction receive/send/both
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketUDP_shutdown(knSocketUDP* socket, knShutdownType direction);
|
||||
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketUDP_close(knSocketUDP* socket);
|
||||
|
||||
///start listening at 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);
|
||||
|
||||
///@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);
|
||||
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../network_types.h"
|
||||
|
||||
typedef struct knSocketUDP {
|
||||
i64 socketfd;
|
||||
knIPV4Endpoint localEndpoint;
|
||||
// TODO socket status enum
|
||||
} knSocketUDP;
|
||||
ktid_declare(knSocketUDP);
|
||||
|
||||
///@note EXAMPLE 1: socket = open(false); bind(socket, localhost:8080); close(socket); - the socket on port 8080 still unavaliable for several minutes
|
||||
///@note EXAMPLE 2: socket = open(true); bind(socket, localhost:8080); close(socket); - the socket on port 8080 can be opened again
|
||||
///@param allowReuse enables binding multiple sockets to single port. Set to TRUE on a listening socket if you want to bind it to the same port after close.
|
||||
///@return Maybe<knSocketUDP*> new socket
|
||||
Maybe knSocketUDP_open(bool allowReuse);
|
||||
|
||||
///@param direction receive/send/both
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketUDP_shutdown(knSocketUDP* socket, knShutdownType direction);
|
||||
|
||||
/// closes file descriptor and frees socket pointer
|
||||
///@return Maybe<void> error or nothing
|
||||
Maybe knSocketUDP_close(knSocketUDP* socket);
|
||||
|
||||
///start listening at 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);
|
||||
|
||||
///@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);
|
||||
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user