From ba6f366845f8b664be71938dc64b57d706f68a21 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 8 Aug 2018 15:52:34 +0800 Subject: +network --- build/libjin/libjin.vcxproj | 2 + libjin/3rdparty/tekcos/tekcos.c | 97 ++++++++++++----------- libjin/3rdparty/tekcos/tekcos.h | 11 --- libjin/Common/Data.h | 23 +++++- libjin/Net/Socket.cpp | 171 ++++++++++++++++++++++++++++++++++++++++ libjin/Net/Socket.h | 57 ++++++++++++++ libjin/modules.h | 1 + test/04Network/main.cpp | 6 +- 8 files changed, 304 insertions(+), 64 deletions(-) create mode 100644 libjin/Net/Socket.cpp create mode 100644 libjin/Net/Socket.h diff --git a/build/libjin/libjin.vcxproj b/build/libjin/libjin.vcxproj index d2f70d0..1e91426 100644 --- a/build/libjin/libjin.vcxproj +++ b/build/libjin/libjin.vcxproj @@ -48,6 +48,7 @@ + @@ -106,6 +107,7 @@ + diff --git a/libjin/3rdparty/tekcos/tekcos.c b/libjin/3rdparty/tekcos/tekcos.c index 9705fe2..17ce7ec 100644 --- a/libjin/3rdparty/tekcos/tekcos.c +++ b/libjin/3rdparty/tekcos/tekcos.c @@ -13,18 +13,18 @@ enum { TK_SUCCESS = 0, - TK_INITFAILED, // init tekcos failed + TK_INITFAILED, // init tekcos failed - TK_COULDNETCREATESOCKET, // couldn't create socket. - TK_CONNECTFAILED, // connect to remote server failed. - TK_BINDSOCKETFAILED, // couldn't bind socket to port - TK_LISTENSOCKETFAILED, // couldn't listen to port - TK_INVALIDSOCKET, // invalid socket - TK_WRONGSOCKETTPYE, // wrong socket type + TK_COULDNETCREATESOCKET, // couldn't create socket. + TK_CONNECTFAILED, // connect to remote server failed. + TK_BINDSOCKETFAILED, // couldn't bind socket to port + TK_LISTENSOCKETFAILED, // couldn't listen to port + TK_INVALIDSOCKET, // invalid socket + TK_WRONGSOCKETTPYE, // wrong socket type - TK_INVALIDTARGET, // cant sendto. + TK_INVALIDTARGET, // cant sendto. - TK_UNKNOWN, // unknown + TK_UNKNOWN, // unknown }; // error code @@ -74,7 +74,6 @@ uint32 tk_strtohl(const char* str) { struct in_addr inaddr; inet_pton(AF_INET, str, (void*)&inaddr); - // host long return ntohl(inaddr.s_addr); } @@ -105,11 +104,10 @@ tk_TCPsocket* tk_tcp_open(tk_IPaddress ip) struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_port = htons(ip.port); - // 32bit address and 16bit port number. addr.sin_family = AF_INET; if (ip.host != INADDR_NONE && (ip.host != INADDR_ANY)) - { // connet to an existed remote server. + { addr.sin_addr.s_addr = htonl(ip.host); if (connect(sk->id, (const struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) { @@ -117,8 +115,9 @@ tk_TCPsocket* tk_tcp_open(tk_IPaddress ip) goto error; } sk->type = SOCKET_TCLIENT; - }else - { // create a listenning server. + } + else + { addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sk->id, (const struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) @@ -148,12 +147,12 @@ int tk_tcp_close(tk_TCPsocket* sk) { if (sk->id == INVALID_SOCKET) goto error; -#ifdef _WIN32 + #ifdef _WIN32 closesocket(sk->id); -#else - close(sk->id); -#endif - free(sk); + #else + close(sk->id); + #endif + free(sk); return 1; } error: @@ -161,23 +160,23 @@ error: return 0; } -int tk_tcp_send(tk_TCPsocket* client, const void* buffer, int bsize, int* sent) +int tk_tcp_send(tk_TCPsocket* client, const void* buffer, int size, int* sent) { - // byte poiter. const char *data = (const char*)buffer; if (client->type != SOCKET_TCLIENT) - {// only cliednt can send stuff. + { state = TK_WRONGSOCKETTPYE; goto error; } - //send(sk->id, buffer, bsize, 0); - int left = bsize; - if(sent) *sent = 0; + int left = size; + if(sent) + *sent = 0; int len = 0; do { len = send(client->id, data, left, 0); if (len > 0) { - if(sent) *sent += len; + if(sent) + *sent += len; left -= len; data += len; } @@ -187,24 +186,27 @@ error: return 0; } -int tk_tcp_recv(tk_TCPsocket* client, char* buffer, int bsize, int* len) +int tk_tcp_recv(tk_TCPsocket* client, char* buffer, int size, int* len) { *len = 0; if (client->type != SOCKET_TCLIENT) - {// only client can be recieved + { state = TK_WRONGSOCKETTPYE; goto error; } + int l = 0; do { - *len = recv(client->id, buffer, bsize, 0); - if (*len == SOCKET_ERROR) + l = recv(client->id, buffer, size - *len, 0); + if (l == SOCKET_ERROR) { state = TK_UNKNOWN; goto error; } - } while (*len == 0 || errno == EINTR); // if was suspended, recieve again. - buffer[*len] = '\0'; + *len += l; + buffer += l; + } while (l == 0 || errno == EINTR); + buffer[0] = '\0'; return 1; error: return 0; @@ -212,9 +214,10 @@ error: tk_TCPsocket* tk_tcp_accept(tk_TCPsocket* server) { + // client tk_TCPsocket* csk = (tk_TCPsocket*) malloc(sizeof(tk_TCPsocket)); if (server->type != SOCKET_TSERVER) - {// only server can accept connection + { state = TK_WRONGSOCKETTPYE; goto error; } @@ -240,38 +243,38 @@ error: int tk_tcp_nonblocking(tk_TCPsocket* sk) { -#if defined(__BEOS__) && defined(SO_NONBLOCK) + #if defined(__BEOS__) && defined(SO_NONBLOCK) { long b = 1; setsockopt(sk->id, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); } -#elif defined(WIN32) + #elif defined(WIN32) { unsigned long mode = 1; ioctlsocket(sk->id, FIONBIO, &mode); } -#elif defined(__OS2__) + #elif defined(__OS2__) { int dontblock = 1; ioctl(sk->id, FIONBIO, &dontblock); } -#endif + #endif return 1; } int tk_tcp_blocking(tk_TCPsocket* sk) { -#if defined(__BEOS__) && defined(SO_NONBLOCK) + #if defined(__BEOS__) && defined(SO_NONBLOCK) { long b = 0; setsockopt(sk->id, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); } -#elif defined(WIN32) + #elif defined(WIN32) { unsigned long mode = 0; ioctlsocket(sk->id, FIONBIO, &mode); } -#elif defined(__OS2__) + #elif defined(__OS2__) { int dontblock = 0; ioctl(sk->id, FIONBIO, &dontblock); @@ -307,11 +310,11 @@ tk_UDPsocket* tk_udp_open(uint16 portnumber) goto error; } if (portnumber <= 0) - {// client, just return + { return sk; } else - {// server, need to bind address to socket + { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_addr.s_addr = htonl(INADDR_ANY); @@ -367,11 +370,11 @@ int tk_udp_close(tk_UDPsocket* sk) { if (sk->id != INVALID_SOCKET) { -#ifdef _WIN32 + #ifdef _WIN32 closesocket(sk->id); -#else - close(sk->id); -#endif + #else + close(sk->id); + #endif } free(sk); } @@ -383,4 +386,4 @@ int tk_freepack(tk_UDPpack* pack) free(pack->data); free(pack); return 1; -} +} \ No newline at end of file diff --git a/libjin/3rdparty/tekcos/tekcos.h b/libjin/3rdparty/tekcos/tekcos.h index e7d8662..0ec22fd 100644 --- a/libjin/3rdparty/tekcos/tekcos.h +++ b/libjin/3rdparty/tekcos/tekcos.h @@ -56,17 +56,11 @@ typedef struct // otherwise, connect to a remote server with given // ip address. tk_TCPsocket* tk_tcp_open(tk_IPaddress ip); - int tk_tcp_close(tk_TCPsocket* sk); - int tk_tcp_send(tk_TCPsocket* client, const void* buffer, int bsize, int* len); - int tk_tcp_recv(tk_TCPsocket* client, char* buffer, int bsize, int* len); - tk_TCPsocket* tk_tcp_accept(tk_TCPsocket* server); - int tk_tcp_nonblocking(tk_TCPsocket* sk); - int tk_tcp_blocking(tk_TCPsocket* sk); /* @@ -89,15 +83,10 @@ typedef struct }tk_UDPpack; tk_UDPsocket* tk_udp_open(uint16 portnumber); - int tk_udp_close(tk_UDPsocket* sk); - int tk_udp_sendto(tk_UDPsocket* sk, tk_UDPpack* pack); - int tk_udp_recvfrom(tk_UDPsocket* sk, tk_UDPpack* pack); - int tk_freepack(tk_UDPpack* pack); - // Get error message if some errors occured. const char* tk_errmsg(); diff --git a/libjin/Common/Data.h b/libjin/Common/Data.h index 38b8c7d..7fcc389 100644 --- a/libjin/Common/Data.h +++ b/libjin/Common/Data.h @@ -4,10 +4,27 @@ namespace jin { - struct DataBuffer + class DataBuffer { - unsigned int len; - char data[0]; + public: + DataBuffer(int n) + : len(n) + { + buffer = new char[len]; + memset(buffer, 0, len); + } + ~DataBuffer() + { + delete[] buffer; + } + char* operator&() + { + return buffer; + } + + private: + char* buffer; + int len; }; } // jin diff --git a/libjin/Net/Socket.cpp b/libjin/Net/Socket.cpp new file mode 100644 index 0000000..f688c74 --- /dev/null +++ b/libjin/Net/Socket.cpp @@ -0,0 +1,171 @@ +#include "Socket.h" + +namespace jin +{ +namespace net +{ + + Socket::Socket(SocketInformation info) + : tcpHandle(nullptr) + , udpHandle(nullptr) + { + type = info.type; + if (type == SocketType::TCP) + { + tk_IPaddress ip; + ip.host = info.address; + ip.port = info.port; + tcpHandle = tk_tcp_open(ip); + } + else if (type == SocketType::UDP) + { + udpHandle = tk_udp_open(info.port); + } + } + + Socket::Socket(SocketType type, unsigned int address, unsigned short port) + { + this->type = type; + if (type == SocketType::TCP) + { + tk_IPaddress ip; + ip.host = address; + ip.port = port; + tcpHandle = tk_tcp_open(ip); + } + else if (type == SocketType::UDP) + { + udpHandle = tk_udp_open(port); + } + } + + Socket::Socket(SocketType type, unsigned short port) + { + this->type = type; + if (type == SocketType::TCP) + { + tk_IPaddress ip; + ip.host = 0; + ip.port = port; + tcpHandle = tk_tcp_open(ip); + } + else if (type == SocketType::UDP) + { + udpHandle = tk_udp_open(port); + } + } + +#if JIN_NET_TEKCOS + + Socket::Socket(tk_TCPsocket* handle) + : tcpHandle(handle) + , udpHandle(nullptr) + { + } + + Socket::Socket(tk_UDPsocket* handle) + : tcpHandle(nullptr) + , udpHandle(handle) + { + } + +#endif // JIN_NET_TEKCOS + + Socket::~Socket() + { + } + + void Socket::configureBlocking(bool blocking) + { + if (type != SocketType::TCP) + return; + #if JIN_NET_TEKCOS + if (blocking) + tk_tcp_blocking(tcpHandle); + else + tk_tcp_nonblocking(tcpHandle); + #endif + } + + Socket* Socket::accept() + { + if (type != SocketType::TCP) + return nullptr; + Socket* client; + #if JIN_NET_TEKCOS + tk_TCPsocket* socket = tk_tcp_accept(tcpHandle); + client = new Socket(socket); + #endif + return client; + } + + int Socket::receive(char* buffer, int size) + { + if (type != SocketType::TCP) + return 0; + #if JIN_NET_TEKCOS + int len; + tk_tcp_recv(tcpHandle, buffer, size, &len); + return len; + #endif + } + + int Socket::send(char* buffer, int size) + { + if (type != SocketType::TCP) + return 0; + #if JIN_NET_TEKCOS + int len; + tk_tcp_send(tcpHandle, buffer, size, &len); + return len; + #endif + } + + void Socket::sendTo(char* buffer, int size, unsigned int address, unsigned int port) + { + if (type != SocketType::UDP) + return; + #if JIN_NET_TEKCOS + tk_UDPpack pack; + pack.data = buffer; + pack.len = size; + pack.ip.host = address; + pack.ip.port = port; + tk_udp_sendto(udpHandle, &pack); + #endif + } + + int Socket::receiveFrom(char* buffer, int size, unsigned int address, unsigned int port) + { + if (type != SocketType::UDP) + return; + int len; + #if JIN_NET_TEKCOS + tk_UDPpack pack; + pack.data = buffer; + pack.len = size; + pack.ip.host = address; + pack.ip.port = port; + tk_udp_recvfrom(udpHandle, &pack); + return pack.len; + #endif + } + + void Socket::close() + { + if (type == SocketType::TCP) + { + #if JIN_NET_TEKCOS + tk_tcp_close(tcpHandle); + #endif + } + else if (type == SocketType::UDP) + { + #if JIN_NET_TEKCOS + tk_udp_close(udpHandle); + #endif + } + } + +} +} \ No newline at end of file diff --git a/libjin/Net/Socket.h b/libjin/Net/Socket.h new file mode 100644 index 0000000..ec60eb9 --- /dev/null +++ b/libjin/Net/Socket.h @@ -0,0 +1,57 @@ +#ifndef __JIN_NET_SOCKET_H +#define __JIN_NET_SOCKET_H +#include "../modules.h" +#if JIN_MODULES_NET + +#include "../3rdparty/tekcos/tekcos.h" + +namespace jin +{ +namespace net +{ + + enum SocketType + { + TCP, + UDP + }; + + struct SocketInformation + { + unsigned int address; + unsigned short port; + SocketType type; + }; + + class Socket + { + public: + Socket(SocketInformation socketInformation); + Socket(SocketType type, unsigned short port); + Socket(SocketType type, unsigned int address, unsigned short port); + ~Socket(); + + void configureBlocking(bool bocking); + + Socket* accept(); + int receive(char* buffer, int size); + int send(char* buffer, int size); + void sendTo(char* buffer, int size, unsigned int address, unsigned int port); + int receiveFrom(char* buffer, int size, unsigned int address, unsigned int port); + void close(); + + private: + #if JIN_NET_TEKCOS + Socket(tk_TCPsocket* tcpHandle); + Socket(tk_UDPsocket* udpHandle); + tk_TCPsocket* tcpHandle; + tk_UDPsocket* udpHandle; + #endif + SocketType type; + }; + +} // net +} // jin + +#endif // JIN_MODULES_NET +#endif // __JIN_NET_SOCKET_H \ No newline at end of file diff --git a/libjin/modules.h b/libjin/modules.h index 06c14df..6cc9336 100644 --- a/libjin/modules.h +++ b/libjin/modules.h @@ -20,6 +20,7 @@ #define JIN_MODULES_MATH 1 #define JIN_MODULES_NET 1 +#define JIN_NET_TEKCOS 1 #define JIN_MODULES_PHYSICS 1 #define JIN_PHYSICS_BOX2D 1 diff --git a/test/04Network/main.cpp b/test/04Network/main.cpp index a792e53..d24e2b0 100644 --- a/test/04Network/main.cpp +++ b/test/04Network/main.cpp @@ -60,13 +60,13 @@ int main(int argc, char* argv[]) Window* wnd = Window::get(); Window::Setting wndSetting; - wndSetting.width = 600; - wndSetting.height = 512; + wndSetting.width = 400; + wndSetting.height = 300; wndSetting.title = "test"; wndSetting.fps = 60; wndSetting.vsync = false; wndSetting.fullscreen = false; - wndSetting.resizable = false; + wndSetting.resizable = true; wnd->init(&wndSetting); Thread t("Count", thread2Runner); -- cgit v1.1-26-g67d0