mirror of
https://github.com/Maschell/libutils.git
synced 2024-11-28 06:34:13 +01:00
Added more net functions and a generic TCPServer
This commit is contained in:
parent
169468ad60
commit
d3657d14eb
1
Makefile
1
Makefile
@ -109,6 +109,7 @@ install:
|
|||||||
@mkdir -p $(INCLUDEDIR)/language/
|
@mkdir -p $(INCLUDEDIR)/language/
|
||||||
@mkdir -p $(INCLUDEDIR)/fs/
|
@mkdir -p $(INCLUDEDIR)/fs/
|
||||||
@cp source/utils/*.h $(INCLUDEDIR)/utils/
|
@cp source/utils/*.h $(INCLUDEDIR)/utils/
|
||||||
|
@cp source/utils/*.hpp $(INCLUDEDIR)/utils/
|
||||||
@cp source/system/*.h $(INCLUDEDIR)/system/
|
@cp source/system/*.h $(INCLUDEDIR)/system/
|
||||||
@cp source/language/*.h $(INCLUDEDIR)/language/
|
@cp source/language/*.h $(INCLUDEDIR)/language/
|
||||||
@cp source/fs/*.h $(INCLUDEDIR)/fs/
|
@cp source/fs/*.h $(INCLUDEDIR)/fs/
|
||||||
|
130
source/utils/TCPServer.cpp
Normal file
130
source/utils/TCPServer.cpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#include "TCPServer.hpp"
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dynamic_libs/nn_act_functions.h>
|
||||||
|
|
||||||
|
#include "logger.h"
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
|
#define wiiu_errno (*__gh_errno_ptr())
|
||||||
|
|
||||||
|
TCPServer::TCPServer(s32 port,s32 priority) {
|
||||||
|
this->port = port;
|
||||||
|
this->sockfd = -1;
|
||||||
|
this->clientfd = -1;
|
||||||
|
memset(&(this->sock_addr),0,sizeof(this->sock_addr));
|
||||||
|
|
||||||
|
pThread = CThread::create(TCPServer::DoTCPThread, (void*)this, CThread::eAttributeAffCore2,priority);
|
||||||
|
pThread->resumeThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPServer::~TCPServer() {
|
||||||
|
CloseSockets();
|
||||||
|
DEBUG_FUNCTION_LINE("Thread will be closed\n");
|
||||||
|
exitThread = 1;
|
||||||
|
|
||||||
|
ICInvalidateRange((void*)&exitThread, 4);
|
||||||
|
DCFlushRange((void*)&exitThread, 4);
|
||||||
|
|
||||||
|
if(pThread != NULL) {
|
||||||
|
DEBUG_FUNCTION_LINE("Deleting it!\n");
|
||||||
|
delete pThread;
|
||||||
|
}
|
||||||
|
DEBUG_FUNCTION_LINE("Thread done\n");
|
||||||
|
pThread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::CloseSockets() {
|
||||||
|
if (this->sockfd != -1) {
|
||||||
|
socketclose(this->sockfd);
|
||||||
|
}
|
||||||
|
if (this->clientfd != -1) {
|
||||||
|
socketclose(this->clientfd);
|
||||||
|
}
|
||||||
|
this->sockfd = -1;
|
||||||
|
this->clientfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::ErrorHandling() {
|
||||||
|
CloseSockets();
|
||||||
|
os_usleep(1000*1000*2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::DoTCPThreadInternal() {
|
||||||
|
s32 ret;
|
||||||
|
s32 len;
|
||||||
|
connected = false;
|
||||||
|
while (1) {
|
||||||
|
if(exitThread) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memset(&(this->sock_addr),0,sizeof(sock_addr));
|
||||||
|
sock_addr.sin_family = AF_INET;
|
||||||
|
sock_addr.sin_port = this->port;
|
||||||
|
sock_addr.sin_addr.s_addr = 0;
|
||||||
|
|
||||||
|
this->sockfd = ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if(ret == -1) {
|
||||||
|
ErrorHandling();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s32 enable = 1;
|
||||||
|
|
||||||
|
setsockopt(this->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
|
||||||
|
|
||||||
|
ret = bind(this->sockfd, (sockaddr *)&sock_addr, 16);
|
||||||
|
if(ret < 0) {
|
||||||
|
ErrorHandling();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ret = listen(this->sockfd, 1);
|
||||||
|
if(ret < 0) {
|
||||||
|
ErrorHandling();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
DEBUG_FUNCTION_LINE("Waiting for a connection\n");
|
||||||
|
if(exitThread) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
len = 16;
|
||||||
|
clientfd = ret = accept(sockfd, (sockaddr *)&(sock_addr), &len);
|
||||||
|
|
||||||
|
if(ret == -1) {
|
||||||
|
ErrorHandling();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!acceptConnection()) {
|
||||||
|
ErrorHandling();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
connected = true;
|
||||||
|
|
||||||
|
DEBUG_FUNCTION_LINE("Connection accepted\n");
|
||||||
|
|
||||||
|
whileLoop();
|
||||||
|
|
||||||
|
DEBUG_FUNCTION_LINE("Client disconnected\n");
|
||||||
|
|
||||||
|
if(clientfd != -1) {
|
||||||
|
socketclose(clientfd);
|
||||||
|
}
|
||||||
|
clientfd = -1;
|
||||||
|
} while(0);
|
||||||
|
DEBUG_FUNCTION_LINE("Closing TCPServer\n");
|
||||||
|
connected = false;
|
||||||
|
onConnectionClosed();
|
||||||
|
CloseSockets();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DEBUG_FUNCTION_LINE("Ending DoTCPThreadInternal\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::DoTCPThread(CThread *thread, void *arg) {
|
||||||
|
TCPServer * args = (TCPServer * )arg;
|
||||||
|
return args->DoTCPThreadInternal();
|
||||||
|
}
|
61
source/utils/TCPServer.hpp
Normal file
61
source/utils/TCPServer.hpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef _TCPSERVER_H_
|
||||||
|
#define _TCPSERVER_H_
|
||||||
|
|
||||||
|
#include <dynamic_libs/socket_functions.h>
|
||||||
|
#include <dynamic_libs/os_functions.h>
|
||||||
|
#include <system/CThread.h>
|
||||||
|
|
||||||
|
class TCPServer {
|
||||||
|
public:
|
||||||
|
TCPServer(s32 port, s32 priority);
|
||||||
|
virtual ~TCPServer();
|
||||||
|
|
||||||
|
bool isConnected() {
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
bool shouldExit() {
|
||||||
|
return (exitThread == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 getClientFD() {
|
||||||
|
return clientfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 getSocketFD() {
|
||||||
|
return sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in getSockAddr() {
|
||||||
|
return sock_addr;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
virtual void CloseSockets();
|
||||||
|
virtual void ErrorHandling();
|
||||||
|
|
||||||
|
static void DoTCPThread(CThread *thread, void *arg);
|
||||||
|
virtual void DoTCPThreadInternal();
|
||||||
|
|
||||||
|
virtual bool acceptConnection() = 0;
|
||||||
|
|
||||||
|
virtual void onConnectionClosed(){
|
||||||
|
DEBUG_FUNCTION_LINE("Default onConnectionClosed \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Called when a connection has be accepted.
|
||||||
|
**/
|
||||||
|
virtual bool whileLoop() = 0;
|
||||||
|
|
||||||
|
struct sockaddr_in sock_addr;
|
||||||
|
volatile s32 sockfd = -1;
|
||||||
|
volatile s32 clientfd = -1;
|
||||||
|
|
||||||
|
s32 port = 0;
|
||||||
|
volatile bool connected = false;
|
||||||
|
|
||||||
|
volatile s32 exitThread = 0;
|
||||||
|
CThread *pThread = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_TCPSERVER_H_
|
@ -1,20 +1,81 @@
|
|||||||
#include "dynamic_libs/socket_functions.h"
|
#include "net.h"
|
||||||
|
#include <dynamic_libs/os_functions.h>
|
||||||
|
#include <dynamic_libs/socket_functions.h>
|
||||||
|
|
||||||
int recvwait(int sock, unsigned char *buffer, int len)
|
static volatile int socket_lock __attribute__((section(".data"))) = 0;
|
||||||
{
|
|
||||||
int recvBytes = 0;
|
|
||||||
|
|
||||||
while(len)
|
s32 recvwait(s32 sock, void *buffer, s32 len) {
|
||||||
{
|
while(socket_lock) {
|
||||||
int ret = recv(sock, buffer, len, 0);
|
os_usleep(1000);
|
||||||
if(ret <= 0) {
|
}
|
||||||
|
s32 ret;
|
||||||
|
while (len > 0) {
|
||||||
|
ret = recv(sock, buffer, len, 0);
|
||||||
|
if(ret < 0) {
|
||||||
|
socket_lock = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
len -= ret;
|
len -= ret;
|
||||||
buffer += ret;
|
buffer = (void *)(((char *) buffer) + ret);
|
||||||
recvBytes += ret;
|
|
||||||
}
|
}
|
||||||
|
socket_lock = 0;
|
||||||
return recvBytes;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 recvbyte(s32 sock) {
|
||||||
|
unsigned char buffer[1];
|
||||||
|
s32 ret;
|
||||||
|
|
||||||
|
ret = recvwait(sock, buffer, 1);
|
||||||
|
if (ret < 0) return ret;
|
||||||
|
return buffer[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 recvword(s32 sock) {
|
||||||
|
u32 result;
|
||||||
|
s32 ret;
|
||||||
|
|
||||||
|
ret = recvwait(sock, &result, 4);
|
||||||
|
if (ret < 0) return ret;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 checkbyte(s32 sock) {
|
||||||
|
while(socket_lock) {
|
||||||
|
os_usleep(1000);
|
||||||
|
}
|
||||||
|
unsigned char buffer[1];
|
||||||
|
s32 ret;
|
||||||
|
|
||||||
|
ret = recv(sock, buffer, 1, MSG_DONTWAIT);
|
||||||
|
socket_lock = 0;
|
||||||
|
if (ret < 0) return ret;
|
||||||
|
if (ret == 0) return -1;
|
||||||
|
return buffer[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 sendwait(s32 sock, const void *buffer, s32 len) {
|
||||||
|
while(socket_lock) {
|
||||||
|
os_usleep(1000);
|
||||||
|
}
|
||||||
|
s32 ret;
|
||||||
|
while (len > 0) {
|
||||||
|
// For some reason the send blocks/crashes if the buffer is too big..
|
||||||
|
int cur_length = len <= 0x30 ? len : 0x30;
|
||||||
|
ret = send(sock, buffer, cur_length, 0);
|
||||||
|
if(ret < 0) {
|
||||||
|
socket_lock = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
len -= ret;
|
||||||
|
buffer = (void *)(((char *) buffer) + ret);
|
||||||
|
}
|
||||||
|
socket_lock = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 sendbyte(s32 sock, unsigned char byte) {
|
||||||
|
unsigned char buffer[1];
|
||||||
|
buffer[0] = byte;
|
||||||
|
return sendwait(sock, buffer, 1);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
#ifndef __NET_H_
|
#ifndef _UTILS_NET_H_
|
||||||
#define __NET_H_
|
#define _UTILS_NET_H_
|
||||||
|
|
||||||
|
#include <dynamic_libs/os_types.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int recvwait(int sock, unsigned char *buffer, int len);
|
s32 recvwait(s32 sock, void *buffer, s32 len);
|
||||||
|
u8 recvbyte(s32 sock);
|
||||||
|
u32 recvword(s32 sock);
|
||||||
|
s32 checkbyte(s32 sock);
|
||||||
|
s32 sendwait(s32 sock, const void *buffer, s32 len);
|
||||||
|
s32 sendbyte(s32 sock, unsigned char byte);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user