TCP and UDP sockets localEndpoint
This commit is contained in:
parent
f2847a819d
commit
c4e102b14c
@ -12,7 +12,7 @@ typedef u16 knPort;
|
|||||||
|
|
||||||
typedef union knIPV4Address {
|
typedef union knIPV4Address {
|
||||||
u32 UintBigEndian;
|
u32 UintBigEndian;
|
||||||
char bytes[4];
|
u8 bytes[4];
|
||||||
} knIPV4Address;
|
} knIPV4Address;
|
||||||
kt_declare(knIPV4Address);
|
kt_declare(knIPV4Address);
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ Maybe knSocketTCP_open(bool allowReuse){
|
|||||||
// set value of REUSEADDR socket option
|
// set value of REUSEADDR socket option
|
||||||
int opt_val = allowReuse;
|
int opt_val = allowReuse;
|
||||||
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
|
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
|
||||||
safethrow("can't set socket options", free(newSocket));
|
safethrow("can't set socket options", knSocketTCP_close(newSocket));
|
||||||
|
|
||||||
return SUCCESS(UniHeapPtr(knSocketTCP, newSocket));
|
return SUCCESS(UniHeapPtr(knSocketTCP, newSocket));
|
||||||
}
|
}
|
||||||
@ -31,54 +31,67 @@ Maybe knSocketTCP_close(knSocketTCP* socket){
|
|||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe knSocketTCP_bindAndListen(knSocketTCP* socket, knIPV4Endpoint localEndp){
|
Maybe knSocketTCP_bind(knSocketTCP* socket, knIPV4Endpoint localEndp){
|
||||||
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(localEndp);
|
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(localEndp);
|
||||||
|
|
||||||
if(bind(socket->socketfd, (void*)&servaddr, sizeof(servaddr)) != 0)
|
if(bind(socket->socketfd, (void*)&servaddr, sizeof(servaddr)) != 0)
|
||||||
safethrow("socket bind failed", ;);
|
safethrow("socket bind failed", ;);
|
||||||
|
|
||||||
if(listen(socket->socketfd, 1024) != 0)
|
|
||||||
safethrow("socket listen failed", ;);
|
|
||||||
|
|
||||||
socket->localEndpoint = localEndp;
|
socket->localEndpoint = localEndp;
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Maybe knSocketTCP_listen(knSocketTCP* socket){
|
||||||
|
if(listen(socket->socketfd, 1024) != 0)
|
||||||
|
safethrow("socket listen failed", ;);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd){
|
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd){
|
||||||
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(remoteEnd);
|
struct sockaddr_in localAddr = {0};
|
||||||
|
struct sockaddr_in remoteAddr = knIPV4Endpoint_toSockaddr(remoteEnd);
|
||||||
|
u64 sockaddr_size = sizeof(localAddr);
|
||||||
|
|
||||||
if(connect(socket->socketfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) !=0)
|
if(connect(socket->socketfd, (struct sockaddr*)&remoteAddr, sizeof(remoteAddr)) != 0)
|
||||||
safethrow("socket connect failed",;);
|
safethrow("socket connect failed", ;);
|
||||||
|
|
||||||
socket->remoteEndpoint=remoteEnd;
|
if(getsockname(socket->socketfd, (struct sockaddr*)&localAddr, (void*)&sockaddr_size) != 0)
|
||||||
|
safethrow("can't get connected socket local address", ;);
|
||||||
|
|
||||||
|
socket->localEndpoint = knIPV4Endpoint_fromSockaddr(localAddr);
|
||||||
|
socket->remoteEndpoint = remoteEnd;
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe knSocketTCP_accept(knSocketTCP* socket){
|
Maybe knSocketTCP_accept(knSocketTCP* socket){
|
||||||
|
struct sockaddr_in localAddr = {0};
|
||||||
struct sockaddr_in remoteAddr = {0};
|
struct sockaddr_in remoteAddr = {0};
|
||||||
u64 remoteAddrSize = sizeof(remoteAddr);
|
u64 sockaddr_size = sizeof(localAddr);
|
||||||
|
|
||||||
i64 client_fd = accept(socket->socketfd, (struct sockaddr*)&remoteAddr, (void*)&remoteAddrSize);
|
i64 client_fd = accept(socket->socketfd, (struct sockaddr*)&remoteAddr, (void*)&sockaddr_size);
|
||||||
if(client_fd == -1 || client_fd == ~0)
|
if(client_fd == -1 || client_fd == ~0)
|
||||||
safethrow("can't accept client connection", ;);
|
safethrow("can't accept client connection", ;);
|
||||||
|
|
||||||
|
if(getsockname(client_fd, (struct sockaddr*)&localAddr, (void*)&sockaddr_size) != 0)
|
||||||
|
safethrow("can't get accepted socket local address", __kn_StdSocket_close(client_fd));
|
||||||
|
|
||||||
// if accept() didn't set remoteAddr for some reason
|
// 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(remoteAddr.sin_addr.s_addr == 0 && remoteAddr.sin_port == 0 && remoteAddr.sin_family == 0){
|
||||||
if(getpeername(client_fd, (struct sockaddr*)&remoteAddr, (void*)&remoteAddrSize) != 0)
|
if(getpeername(client_fd, (struct sockaddr*)&remoteAddr, (void*)&sockaddr_size) != 0)
|
||||||
safethrow("can't get connected client address", ;);
|
safethrow("can't get accepted socket remote address", __kn_StdSocket_close(client_fd));
|
||||||
}
|
}
|
||||||
|
|
||||||
knSocketTCP* clientSocket = malloc(sizeof(knSocketTCP));
|
knSocketTCP* clientSocket = malloc(sizeof(knSocketTCP));
|
||||||
clientSocket->socketfd = client_fd;
|
clientSocket->socketfd = client_fd;
|
||||||
clientSocket->localEndpoint = socket->localEndpoint;
|
clientSocket->localEndpoint = knIPV4Endpoint_fromSockaddr(localAddr);
|
||||||
clientSocket->remoteEndpoint = knIPV4Endpoint_fromSockaddr(remoteAddr);
|
clientSocket->remoteEndpoint = knIPV4Endpoint_fromSockaddr(remoteAddr);
|
||||||
return SUCCESS(UniHeapPtr(knSocketTCP, clientSocket));
|
return SUCCESS(UniHeapPtr(knSocketTCP, clientSocket));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength){
|
Maybe knSocketTCP_send(knSocketTCP* socket, void* _buf, u32 dataLength){
|
||||||
|
char* buf = _buf;
|
||||||
u32 sentTotal = 0;
|
u32 sentTotal = 0;
|
||||||
while(sentTotal < dataLength){
|
while(sentTotal < dataLength){
|
||||||
int sentCount = send(socket->socketfd, buffer+sentTotal, dataLength-sentTotal, 0);
|
int sentCount = send(socket->socketfd, buf+sentTotal, dataLength-sentTotal, 0);
|
||||||
if(sentCount == -1){
|
if(sentCount == -1){
|
||||||
safethrow(
|
safethrow(
|
||||||
cptr_concat("can't send ", toString_u64(dataLength-sentTotal,0,0),
|
cptr_concat("can't send ", toString_u64(dataLength-sentTotal,0,0),
|
||||||
@ -93,15 +106,17 @@ Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength){
|
|||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe knSocketTCP_receive(knSocketTCP* socket, char* buffer, u32 bufferLength){
|
Maybe knSocketTCP_receive(knSocketTCP* socket, void* _buf, u32 bufferLength){
|
||||||
int receivedCount = recv(socket->socketfd, buffer, bufferLength, 0);
|
char* buf = _buf;
|
||||||
|
int receivedCount = recv(socket->socketfd, buf, bufferLength, 0);
|
||||||
if(receivedCount == -1 || receivedCount == 0)
|
if(receivedCount == -1 || receivedCount == 0)
|
||||||
safethrow("can't receive data from socket", ;)
|
safethrow("can't receive data from socket", ;)
|
||||||
|
|
||||||
return SUCCESS(UniUInt64(receivedCount));
|
return SUCCESS(UniUInt64(receivedCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe knSocketTCP_receiveN(knSocketTCP* socket, char* buf, u32 bufsize, u32 n){
|
Maybe knSocketTCP_receiveN(knSocketTCP* socket, void* _buf, u32 bufsize, u32 n){
|
||||||
|
char* buf = _buf;
|
||||||
if(bufsize < n)
|
if(bufsize < n)
|
||||||
safethrow(ERR_UNEXPECTEDVAL, ;);
|
safethrow(ERR_UNEXPECTEDVAL, ;);
|
||||||
|
|
||||||
|
|||||||
@ -27,9 +27,13 @@ Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction);
|
|||||||
///@return Maybe<void> error or nothing
|
///@return Maybe<void> error or nothing
|
||||||
Maybe knSocketTCP_close(knSocketTCP* socket);
|
Maybe knSocketTCP_close(knSocketTCP* socket);
|
||||||
|
|
||||||
/// binds socket to a local endpoint and starts listening for incoming TCP connections
|
/// binds socket to a local endpoint
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketTCP_bind(knSocketTCP* socket, knIPV4Endpoint localEndp);
|
||||||
|
|
||||||
|
/// begins listening for incoming TCP connections
|
||||||
|
Maybe knSocketTCP_listen(knSocketTCP* socket);
|
||||||
///@return Maybe<void> error or nothing
|
///@return Maybe<void> error or nothing
|
||||||
Maybe knSocketTCP_bindAndListen(knSocketTCP* socket, knIPV4Endpoint localEndp);
|
|
||||||
|
|
||||||
/// establishes TCP connection with a remote endpoint
|
/// establishes TCP connection with a remote endpoint
|
||||||
///@return Maybe<void> error or nothing
|
///@return Maybe<void> error or nothing
|
||||||
@ -42,18 +46,18 @@ Maybe knSocketTCP_accept(knSocketTCP* socket);
|
|||||||
///@param buffer buffer for receiving data
|
///@param buffer buffer for receiving data
|
||||||
///@param dataLength 0-4294967295
|
///@param dataLength 0-4294967295
|
||||||
///@return Maybe<void>
|
///@return Maybe<void>
|
||||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength);
|
Maybe knSocketTCP_send(knSocketTCP* socket, void* buffer, u32 dataLength);
|
||||||
|
|
||||||
/// receives a package of any size
|
/// receives a package of any size
|
||||||
/// (by TCP 32 bytes han be sent as 32x1byte, 4x8byte, 32x1byte or in any other combination)
|
/// (by TCP 32 bytes han be sent as 32x1byte, 4x8byte, 32x1byte or in any other combination)
|
||||||
///@param buffer buffer for receiving data
|
///@param buffer buffer for receiving data
|
||||||
///@param bufferLength 0-4294967295
|
///@param bufferLength 0-4294967295
|
||||||
///@return Maybe<u64> received bytes amount
|
///@return Maybe<u64> received bytes amount
|
||||||
Maybe knSocketTCP_receive(knSocketTCP* socket, char* buffer, u32 bufferLength);
|
Maybe knSocketTCP_receive(knSocketTCP* socket, void* buffer, u32 bufferLength);
|
||||||
|
|
||||||
/// receives a package of size n
|
/// receives a package of size n
|
||||||
///@return Maybe<void>
|
///@return Maybe<void>
|
||||||
Maybe knSocketTCP_receiveN(knSocketTCP* socket, char* buf, u32 bufsize, u32 n);
|
Maybe knSocketTCP_receiveN(knSocketTCP* socket, void* buf, u32 bufsize, u32 n);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ Maybe knSocketUDP_open(bool allowReuse){
|
|||||||
// set value of REUSEADDR socket option
|
// set value of REUSEADDR socket option
|
||||||
int opt_val = allowReuse;
|
int opt_val = allowReuse;
|
||||||
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
|
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
|
||||||
safethrow("can't set socket options", free(newSocket));
|
safethrow("can't set socket options", knSocketUDP_close(newSocket));
|
||||||
|
|
||||||
return SUCCESS(UniHeapPtr(knSocketUDP, newSocket));
|
return SUCCESS(UniHeapPtr(knSocketUDP, newSocket));
|
||||||
}
|
}
|
||||||
@ -63,6 +63,14 @@ Maybe knSocketUDP_sendTo(knSocketUDP* socket, char* buffer, u32 dataLength, knIP
|
|||||||
;);
|
;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in localAddr = {0};
|
||||||
|
u64 sockaddr_size = sizeof(localAddr);
|
||||||
|
|
||||||
|
if(getsockname(socket->socketfd, (struct sockaddr*)&localAddr, (void*)&sockaddr_size) != 0)
|
||||||
|
safethrow("can't get implicitely bound socket local address", ;);
|
||||||
|
|
||||||
|
socket->localEndpoint = knIPV4Endpoint_fromSockaddr(localAddr);
|
||||||
|
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -81,6 +81,7 @@ char* __unknownErr( );
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define tryLast(_funcCall, _result, ON_EXIT) Maybe _result=_funcCall; if(_result.errmsg){ \
|
#define tryLast(_funcCall, _result, ON_EXIT) Maybe _result=_funcCall; if(_result.errmsg){ \
|
||||||
|
ON_EXIT; \
|
||||||
_result.errmsg=__extendErrMsg(_result.errmsg, __FILE__,__LINE__,__func__); \
|
_result.errmsg=__extendErrMsg(_result.errmsg, __FILE__,__LINE__,__func__); \
|
||||||
__EXIT(_result.errmsg); \
|
__EXIT(_result.errmsg); \
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,8 +47,12 @@ typedef struct {
|
|||||||
void* tcp_client_connect_async(void* _data){
|
void* tcp_client_connect_async(void* _data){
|
||||||
tcp_client_connect_async_data* data = _data;
|
tcp_client_connect_async_data* data = _data;
|
||||||
tryLast(knSocketTCP_connect(data->socket_client, data->serverEnd), _m8531,;);
|
tryLast(knSocketTCP_connect(data->socket_client, data->serverEnd), _m8531,;);
|
||||||
|
|
||||||
kprintf_safe("\e[92mclient socket connected to server\n");
|
kprintf_safe("\e[92mclient socket connected to server\n");
|
||||||
|
|
||||||
|
char* adrstr = knIPV4Endpoint_toString(&data->socket_client->localEndpoint);
|
||||||
|
kprintf("\e[92mclient socket was implicitely bound to %s\n\e[94m", adrstr);
|
||||||
|
free(adrstr);
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -63,7 +67,8 @@ static void test_tcp(){
|
|||||||
socket_server=m_socketS.value.VoidPtr;
|
socket_server=m_socketS.value.VoidPtr;
|
||||||
kprintf("\e[92mTCP server socket created\n");
|
kprintf("\e[92mTCP server socket created\n");
|
||||||
|
|
||||||
tryLast(knSocketTCP_bindAndListen(socket_server, serverEnd), _m81775, ;)
|
tryLast(knSocketTCP_bind(socket_server, serverEnd), _m81775, ;)
|
||||||
|
tryLast(knSocketTCP_listen(socket_server), _m88775, ;)
|
||||||
kprintf("\e[92mserver socket is listening\n");
|
kprintf("\e[92mserver socket is listening\n");
|
||||||
}
|
}
|
||||||
// client
|
// client
|
||||||
@ -161,6 +166,10 @@ void test_udp(){
|
|||||||
const char client_msg[] = "ping";
|
const char client_msg[] = "ping";
|
||||||
tryLast(knSocketUDP_sendTo(socket_client, client_msg, sizeof(client_msg), serverEnd), _mu75q2, ;);
|
tryLast(knSocketUDP_sendTo(socket_client, client_msg, sizeof(client_msg), serverEnd), _mu75q2, ;);
|
||||||
kprintf("\e[92mmessage sent to server\n\e[94m");
|
kprintf("\e[92mmessage sent to server\n\e[94m");
|
||||||
|
|
||||||
|
char* adrstr = knIPV4Endpoint_toString(&socket_client->localEndpoint);
|
||||||
|
kprintf("\e[92mclient socket was implicitely bound to %s\n\e[94m", adrstr);
|
||||||
|
free(adrstr);
|
||||||
}
|
}
|
||||||
// server
|
// server
|
||||||
{
|
{
|
||||||
|
|||||||
@ -24,19 +24,19 @@ void test_network();
|
|||||||
inline void test_all(){
|
inline void test_all(){
|
||||||
kprintf("\e[97mkerep tests are starting!\n");
|
kprintf("\e[97mkerep tests are starting!\n");
|
||||||
optime(__func__, 1,
|
optime(__func__, 1,
|
||||||
test_cptr();
|
// test_cptr();
|
||||||
test_type_system();
|
// test_type_system();
|
||||||
test_string();
|
// test_string();
|
||||||
test_safethrow();
|
// test_safethrow();
|
||||||
test_searchtree();
|
// test_searchtree();
|
||||||
test_autoarr();
|
// test_autoarr();
|
||||||
test_autoarrVsVector();
|
// test_autoarrVsVector();
|
||||||
test_rng_algorithms();
|
// test_rng_algorithms();
|
||||||
test_kprint_colors();
|
// test_kprint_colors();
|
||||||
test_kprint();
|
// test_kprint();
|
||||||
test_hash_functions();
|
// test_hash_functions();
|
||||||
test_hashtable();
|
// test_hashtable();
|
||||||
test_dtsod();
|
// test_dtsod();
|
||||||
test_network();
|
test_network();
|
||||||
kprintf("\e[96m--------------------------------------\e[0m\n");
|
kprintf("\e[96m--------------------------------------\e[0m\n");
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user