aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2018-08-08 15:52:34 +0800
committerchai <chaifix@163.com>2018-08-08 15:52:34 +0800
commitba6f366845f8b664be71938dc64b57d706f68a21 (patch)
tree93d61c3a93c0de4e5f1176ab9ddc43d68d607a77
parent35d0affb2b19a38ae43ac991021dd3c888dc3aa6 (diff)
+network
-rw-r--r--build/libjin/libjin.vcxproj2
-rw-r--r--libjin/3rdparty/tekcos/tekcos.c97
-rw-r--r--libjin/3rdparty/tekcos/tekcos.h11
-rw-r--r--libjin/Common/Data.h23
-rw-r--r--libjin/Net/Socket.cpp171
-rw-r--r--libjin/Net/Socket.h57
-rw-r--r--libjin/modules.h1
-rw-r--r--test/04Network/main.cpp6
8 files changed, 304 insertions, 64 deletions
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 @@
<ClCompile Include="..\..\libjin\Math\Matrix.cpp" />
<ClCompile Include="..\..\libjin\Math\Vector.cpp" />
<ClCompile Include="..\..\libjin\Net\Net.cpp" />
+ <ClCompile Include="..\..\libjin\Net\Socket.cpp" />
<ClCompile Include="..\..\libjin\Thread\Thread.cpp" />
<ClCompile Include="..\..\libjin\Tilemap\Tilemap.cpp" />
<ClCompile Include="..\..\libjin\Time\Timer.cpp" />
@@ -106,6 +107,7 @@
<ClInclude Include="..\..\libjin\Math\Vector.h" />
<ClInclude Include="..\..\libjin\modules.h" />
<ClInclude Include="..\..\libjin\Net\Net.h" />
+ <ClInclude Include="..\..\libjin\Net\Socket.h" />
<ClInclude Include="..\..\libjin\Physics\Physics.h" />
<ClInclude Include="..\..\libjin\Physics\Rigid.h" />
<ClInclude Include="..\..\libjin\Thread\Thread.h" />
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);