12 Commits
0.3.0 ... 0.4.0

38 changed files with 937 additions and 371 deletions

View File

@@ -1,11 +1,7 @@
language: language: cpp
- cpp
sudo: false sudo: required
dist: trusty
os:
- linux
- osx
branches: branches:
only: only:
@@ -18,37 +14,75 @@ addons:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
packages: packages:
- g++-4.9 - g++-4.9
- expect
- binutils-mingw-w64-x86-64 # 64bit MinGW
- gcc-mingw-w64-x86-64
- g++-mingw-w64-x86-64
matrix:
include:
- os: linux
env: CONF=release BUILDER=gcc TARGET=Linux TAG=Linux COMPILATOR_OPTION="--compilator-version=4.9" GCOV=--gcov
compiler: gcc
- os: linux
env: CONF=debug BUILDER=clang TARGET=Linux
compiler: clang
- os: linux
env: CONF=release BUILDER=gcc TARGET=Windows TAG=Mingw
compiler: x86_64-w64-mingw32-gcc
- os: linux
env: CONF=release BUILDER=gcc TARGET=Android TAG=Android DISABLE_PACKAGE=-p
compiler: gcc
- os: osx
env: CONF=release BUILDER=clang TARGET=MacOs TAG=MacOs
compiler: clang
- os: osx
env: CONF=release BUILDER=clang TARGET=IOs TAG=IOs
compiler: clang
install: install:
- cd ..
- pip install --user lutin - pip install --user lutin
- if [ "$TAG" == "Android" ]; then
env: git clone --depth 1 --branch master https://github.com/HeeroYui/android-download-tool;
- CONF=debug BOARD=Linux BUILDER=clang GCOV= ./android-download-tool/dl-android.sh;
- CONF=release BOARD=Linux BUILDER=clang GCOV= fi
- CONF=debug BOARD=Linux BUILDER=gcc GCOV= - git clone --depth 1 --branch master https://github.com/atria-soft/ci.git
- CONF=release BOARD=Linux BUILDER=gcc GCOV= - cd -
- CONF=debug BOARD=Linux BUILDER=gcc GCOV=--gcov
before_script: before_script:
- cd .. - cd ..
- wget http://atria-soft.com/ci/coverage_send.py - git clone https://github.com/atria-soft/elog.git -b $TRAVIS_BRANCH
- wget http://atria-soft.com/ci/test_send.py - git clone https://github.com/atria-soft/ememory.git -b $TRAVIS_BRANCH
- wget http://atria-soft.com/ci/warning_send.py - git clone https://github.com/atria-soft/echrono.git -b $TRAVIS_BRANCH
- git clone https://github.com/atria-soft/etk.git - git clone https://github.com/atria-soft/algue.git -b $TRAVIS_BRANCH
- git clone https://github.com/atria-soft/etk.git -b $TRAVIS_BRANCH
- git clone https://github.com/atria-soft/ethread.git -b $TRAVIS_BRANCH
- git clone https://github.com/generic-library/gtest-lutin.git --recursive - git clone https://github.com/generic-library/gtest-lutin.git --recursive
- git clone https://github.com/generic-library/z-lutin.git --recursive
- git clone https://github.com/generic-library/openssl-lutin.git --recursive
- pwd - pwd
- ls -l - ls -l
- if [ "$BUILDER" == "gcc" ]; then COMPILATOR_OPTION="--compilator-version=4.9"; else COMPILATOR_OPTION=""; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then
export PATH=$PATH:/Users/travis/Library/Python/2.7/bin/;
fi
- ./ci/build_send.py --tag=$TAG --status=START;
script: script:
- lutin -w -j4 -C -P -c $BUILDER $COMPILATOR_OPTION -m $CONF $GCOV -p enet-test - lutin -w -j4 -C -P -t$TARGET -c $BUILDER $COMPILATOR_OPTION $BUS -m $CONF $GCOV $DISABLE_PACKAGE enet-*; STATUS=$?
- ./ci/build_send.py --tag=$TAG --status="$STATUS";
after_script: after_script:
- if [ "$GCOV" != "" ]; then python ./warning_send.py --find-path ./out/Linux_x86_64/$CONF/build/$BUILDER/enet/ ; fi - if [ "$GCOV" != "" ]; then
- ./out/Linux_x86_64/$CONF/staging/$BUILDER/enet-test/usr/bin/enet-test -l6 | tee out_test.txt ./ci/warning_send.py --find-path ./out/Linux_x86_64/$CONF/build/$BUILDER/enet/;
- if [ "$GCOV" != "" ]; then python ./test_send.py --file=out_test.txt; fi fi
- if [ "$GCOV" != "" ]; then lutin -C -P -c $BUILDER $COMPILATOR_OPTION -m $CONF -p enet?gcov; fi - lutin -w -j4 -C -P -t$TARGET -c $BUILDER $COMPILATOR_OPTION $BUS -m $CONF $GCOV $DISABLE_PACKAGE enet-test-client-websocket?run:--elog-level=3 | tee out_test.txt
- if [ "$GCOV" != "" ]; then python ./coverage_send.py --json=out/Linux_x86_64/$CONF/build/$BUILDER/enet/enet_coverage.json; fi - if [ "$GCOV" != "" ]; then
./ci/test_send.py --file=out_test.txt;
lutin -C -P -t $TARGET -c $BUILDER $COMPILATOR_OPTION $BUS -m $CONF -p enet?gcov;
./ci/coverage_send.py --json=out/Linux_x86_64/$CONF/build/$BUILDER/enet/enet_coverage.json;
fi
notifications: notifications:
email: email:

View File

@@ -3,18 +3,67 @@ enet
`enet` is a network abstraction layer for ewol `enet` is a network abstraction layer for ewol
Release (master)
----------------
[![Build Status](https://travis-ci.org/atria-soft/enet.svg?branch=master)](https://travis-ci.org/atria-soft/enet) [![Build Status](https://travis-ci.org/atria-soft/enet.svg?branch=master)](https://travis-ci.org/atria-soft/enet)
[![Coverage Status](http://atria-soft.com/ci/coverage/atria-soft/enet.svg?branch=master)](http://atria-soft.com/ci/atria-soft/enet) [![Coverage Status](http://atria-soft.com/ci/coverage/atria-soft/enet.svg?branch=master)](http://atria-soft.com/ci/atria-soft/enet)
[![Test Status](http://atria-soft.com/ci/test/atria-soft/enet.svg?branch=master)](http://atria-soft.com/ci/atria-soft/enet) [![Test Status](http://atria-soft.com/ci/test/atria-soft/enet.svg?branch=master)](http://atria-soft.com/ci/atria-soft/enet)
[![Warning Status](http://atria-soft.com/ci/warning/atria-soft/enet.svg?branch=master)](http://atria-soft.com/ci/atria-soft/enet) [![Warning Status](http://atria-soft.com/ci/warning/atria-soft/enet.svg?branch=master)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=master&tag=Linux)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=master&tag=MacOs)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=master&tag=Mingw)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=master&tag=Android)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=master&tag=IOs)](http://atria-soft.com/ci/atria-soft/enet)
Developement (dev)
------------------
[![Build Status](https://travis-ci.org/atria-soft/enet.svg?branch=dev)](https://travis-ci.org/atria-soft/enet)
[![Coverage Status](http://atria-soft.com/ci/coverage/atria-soft/enet.svg?branch=dev)](http://atria-soft.com/ci/atria-soft/enet)
[![Test Status](http://atria-soft.com/ci/test/atria-soft/enet.svg?branch=dev)](http://atria-soft.com/ci/atria-soft/enet)
[![Warning Status](http://atria-soft.com/ci/warning/atria-soft/enet.svg?branch=dev)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=dev&tag=Linux)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=dev&tag=MacOs)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=dev&tag=Mingw)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=dev&tag=Android)](http://atria-soft.com/ci/atria-soft/enet)
[![Build Status](http://atria-soft.com/ci/build/atria-soft/enet.svg?branch=dev&tag=IOs)](http://atria-soft.com/ci/atria-soft/enet)
Instructions Instructions
============ ============
To compile and use see 'ewol' or 'edn' project download Build system:
----------------------
sudo pip install lutin
sudo pip install pillow
download the software:
----------------------
mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY
git clone https://github.com/atria-soft/elog.git
git clone https://github.com/atria-soft/ememory.git
git clone https://github.com/atria-soft/echrono.git
git clone https://github.com/atria-soft/algue.git
git clone https://github.com/atria-soft/etk.git
git clone https://github.com/atria-soft/enet.git
git clone https://github.com/generic-library/gtest-lutin.git --recursive
git clone https://github.com/generic-library/z-lutin.git --recursive
git clone https://github.com/generic-library/openssl-lutin.git --recursive
Compile software:
-----------------
cd WORKING_DIRECTORY
lutin -C -P enet-test?build?run
License (APACHE v2.0) License (APACHE v2.0)
===================== =====================

76
doc/build.md Normal file
View File

@@ -0,0 +1,76 @@
Build lib & build sample {#enet_build}
========================
@tableofcontents
Download: {#enet_build_download}
=========
enet use some tools to manage source and build it:
lutin (build-system): {#enet_build_download_lutin}
---------------------
```{.sh}
pip install lutin --user
# optionnal dependency of lutin (manage image changing size for application release)
pip install pillow --user
```
dependency: {#enet_build_download_dependency}
-----------
```{.sh}
mkdir framework
cd framework
git clone https://github.com/atria-soft/etk.git
git clone https://github.com/atria-soft/ememory.git
git clone https://github.com/atria-soft/algue.git
git clone https://github.com/generic-library/gtest-lutin.git --recursive
git clone https://github.com/generic-library/z-lutin.git --recursive
git clone https://github.com/generic-library/openssl-lutin.git --recursive
cd ..
```
sources: {#enet_build_download_sources}
--------
```{.sh}
cd framework
git clone https://github.com/atria-soft/enet.git
cd ..
```
Build: {#enet_build_build}
======
library: {#enet_build_build_library}
--------
```{.sh}
lutin -mdebug enet
```
Sample: {#enet_build_build_sample}
-------
```{.sh}
lutin -mdebug enet-server-websocket enet-client-websocket
```
Run sample: {#enet_build_run_sample}
===========
```{.sh}
lutin -mdebug enet-server-websocket?run
```
In an other bash:
```{.sh}
lutin -mdebug enet-client-websocket?run
```

64
doc/mainpage.md Normal file
View File

@@ -0,0 +1,64 @@
ENET library {#mainpage}
=============
@tableofcontents
What is ENET: {#enet_mainpage_what}
==============
`enet` is a network abstraction layer for ewol
What it does: {#enet_mainpage_what_it_does}
-------------
Provide some acces on Network interface for all platform (simplify API)
ENET is dependent of the STL (compatible with MacOs stl (CXX))
It provide some simple interface for TCP, HTTP, webSocket in server and client modes
What is the TODO list: {#enet_mainpage_todo}
----------------------
Create a full complient interface for every protocol ...
this is in dev
What languages are supported? {#enet_mainpage_language}
=============================
ENET is written in C++.
Are there any licensing restrictions? {#enet_mainpage_license_restriction}
=====================================
ENET is **FREE software** and _all sub-library are FREE and staticly linkable !!!_
License (APACHE-2.0) {#enet_mainpage_license}
====================
Copyright ENET Edouard DUPIN
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
<http://www.apache.org/licenses/LICENSE-2.0>
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Other pages {#enet_mainpage_sub_page}
===========
- @ref enet_build
- [**ewol coding style**](http://atria-soft.github.io/ewol/ewol_coding_style.html)

33
doxy_enet.py Normal file
View File

@@ -0,0 +1,33 @@
#!/usr/bin/python
import os
import doxy.module as module
import doxy.debug as debug
import doxy.tools as tools
def create(target, module_name):
my_module = module.Module(__file__, module_name)
my_module.set_version("version.txt")
my_module.set_title("enet: Ewol network abstraction")
my_module.set_website("http://atria-soft.github.io/" + module_name)
my_module.set_website_sources("http://github.com/atria-soft/" + module_name)
my_module.add_path([
module_name,
"doc"
])
my_module.add_depend([
'etk',
'ememory',
#'algue'
])
my_module.add_exclude_symbols([
'*operator<<*',
])
my_module.add_exclude_file([
'debug.hpp',
])
my_module.add_file_patterns([
'*.hpp',
'*.md',
])
return my_module

View File

@@ -4,6 +4,6 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <enet/debug.h> #include <enet/debug.hpp>
#include <enet/Ftp.h> #include <enet/Ftp.hpp>
#include <string.h> #include <cstring>

View File

@@ -4,12 +4,12 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <enet/debug.h> #include <enet/debug.hpp>
#include <enet/Http.h> #include <enet/Http.hpp>
#include <map> #include <map>
#include <etk/stdTools.h> #include <etk/stdTools.hpp>
#include <string.h> #include <cstring>
#include <unistd.h>
static std::string escapeChar(const std::string& _value) { static std::string escapeChar(const std::string& _value) {
return _value; return _value;
@@ -147,7 +147,7 @@ void enet::Http::start() {
} }
while ( m_threadRunning == true while ( m_threadRunning == true
&& m_connection.getConnectionStatus() != enet::Tcp::status::link) { && m_connection.getConnectionStatus() != enet::Tcp::status::link) {
usleep(50000); std::this_thread::sleep_for(std::chrono::milliseconds(50));
} }
//ethread::setPriority(*m_receiveThread, -6); //ethread::setPriority(*m_receiveThread, -6);
ENET_DEBUG("connect [STOP]"); ENET_DEBUG("connect [STOP]");
@@ -208,21 +208,21 @@ namespace etk {
} }
template <> template <>
bool from_string<enum enet::HTTPReqType>(enum enet::HTTPReqType& _variableRet, const std::string& _value) { bool from_string<enum enet::HTTPReqType>(enum enet::HTTPReqType& _variableRet, const std::string& _value) {
_variableRet = enet::HTTPReqType::GET; _variableRet = enet::HTTPReqType::HTTP_GET;
if (_value == "GET") { if (_value == "GET") {
_variableRet = enet::HTTPReqType::GET; _variableRet = enet::HTTPReqType::HTTP_GET;
return true; return true;
} else if (_value == "HEAD") { } else if (_value == "HEAD") {
_variableRet = enet::HTTPReqType::HEAD; _variableRet = enet::HTTPReqType::HTTP_HEAD;
return true; return true;
} else if (_value == "POST") { } else if (_value == "POST") {
_variableRet = enet::HTTPReqType::POST; _variableRet = enet::HTTPReqType::HTTP_POST;
return true; return true;
} else if (_value == "PUT") { } else if (_value == "PUT") {
_variableRet = enet::HTTPReqType::PUT; _variableRet = enet::HTTPReqType::HTTP_PUT;
return true; return true;
} else if (_value == "DELETE") { } else if (_value == "DELETE") {
_variableRet = enet::HTTPReqType::DELETE; _variableRet = enet::HTTPReqType::HTTP_DELETE;
return true; return true;
} }
return false; return false;
@@ -230,11 +230,11 @@ namespace etk {
template <> template <>
std::string to_string<enum enet::HTTPReqType>(const enum enet::HTTPReqType& _value) { std::string to_string<enum enet::HTTPReqType>(const enum enet::HTTPReqType& _value) {
switch (_value) { switch (_value) {
case enet::HTTPReqType::GET: return "GET"; case enet::HTTPReqType::HTTP_GET: return "GET";
case enet::HTTPReqType::HEAD: return "HEAD"; case enet::HTTPReqType::HTTP_HEAD: return "HEAD";
case enet::HTTPReqType::POST: return "POST"; case enet::HTTPReqType::HTTP_POST: return "POST";
case enet::HTTPReqType::PUT: return "PUT"; case enet::HTTPReqType::HTTP_PUT: return "PUT";
case enet::HTTPReqType::DELETE: return "DELETE"; case enet::HTTPReqType::HTTP_DELETE: return "DELETE";
} }
return "UNKNOW"; return "UNKNOW";
} }
@@ -364,7 +364,7 @@ void enet::Http::getHeader() {
char type; char type;
int32_t len = m_connection.read(&type, 1); int32_t len = m_connection.read(&type, 1);
if (len == 0) { if (len == 0) {
usleep(1); std::this_thread::sleep_for(std::chrono::microseconds(1));
continue; continue;
} }
header += type; header += type;

View File

@@ -5,11 +5,11 @@
*/ */
#pragma once #pragma once
#include <enet/Tcp.h> #include <enet/Tcp.hpp>
#include <vector> #include <vector>
#include <map> #include <map>
#include <thread> #include <thread>
#include <ethread/tools.h> #include <ethread/tools.hpp>
namespace enet { namespace enet {
enum class HTTPAnswerCode { enum class HTTPAnswerCode {
@@ -156,11 +156,11 @@ namespace enet {
} }
}; };
enum class HTTPReqType { enum class HTTPReqType {
GET, HTTP_GET,
HEAD, HTTP_HEAD,
POST, HTTP_POST,
PUT, HTTP_PUT,
DELETE, HTTP_DELETE,
}; };
std::ostream& operator <<(std::ostream& _os, enum enet::HTTPReqType _obj); std::ostream& operator <<(std::ostream& _os, enum enet::HTTPReqType _obj);
class HttpRequest : public HttpHeader { class HttpRequest : public HttpHeader {
@@ -169,7 +169,7 @@ namespace enet {
enum HTTPReqType m_req; enum HTTPReqType m_req;
std::string m_uri; std::string m_uri;
public: public:
HttpRequest(enum enet::HTTPReqType _type=enet::HTTPReqType::GET); HttpRequest(enum enet::HTTPReqType _type=enet::HTTPReqType::HTTP_GET);
void display() const; void display() const;
std::string generate() const; std::string generate() const;
void setType(enum enet::HTTPReqType _value) { void setType(enum enet::HTTPReqType _value) {

View File

@@ -4,17 +4,23 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <enet/debug.h> #include <enet/debug.hpp>
#include <enet/Tcp.h> #include <enet/Tcp.hpp>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <cerrno>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <cstring>
#include <etk/stdTools.h> #include <etk/stdTools.hpp>
#include <netinet/tcp.h>
#ifdef __TARGET_OS__Windows
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#endif
bool enet::Tcp::setTCPNoDelay(bool _enabled) { bool enet::Tcp::setTCPNoDelay(bool _enabled) {
if (m_socketId >= 0) { if (m_socketId >= 0) {
@@ -29,37 +35,40 @@ bool enet::Tcp::setTCPNoDelay(bool _enabled) {
enet::Tcp::Tcp() : enet::Tcp::Tcp() :
#ifdef __TARGET_OS__Windows
m_socketId(INVALID_SOCKET),
#else
m_socketId(-1), m_socketId(-1),
#endif
m_name(), m_name(),
m_status(status::error) { m_status(status::error) {
} }
enet::Tcp::Tcp(int32_t _idSocket, const std::string& _name) : #ifdef __TARGET_OS__Windows
enet::Tcp::Tcp(SOCKET _idSocket, const std::string& _name) :
#else
enet::Tcp::Tcp(int32_t _idSocket, const std::string& _name) :
#endif
m_socketId(_idSocket), m_socketId(_idSocket),
m_name(_name), m_name(_name),
m_status(status::link) { m_status(status::link) {
#if 1
//Initialize the pollfd structure
memset(m_fds, 0 , sizeof(m_fds));
//Set up the initial listening socket
m_fds[0].fd = _idSocket;
m_fds[0].events = POLLIN | POLLERR;
#endif
} }
enet::Tcp::Tcp(Tcp&& _obj) : enet::Tcp::Tcp(Tcp&& _obj) :
m_socketId(_obj.m_socketId), m_socketId(_obj.m_socketId),
m_name(_obj.m_name), m_name(_obj.m_name),
m_status(_obj.m_status) { m_status(_obj.m_status) {
#ifdef __TARGET_OS__Windows
_obj.m_socketId = INVALID_SOCKET;
#else
_obj.m_socketId = -1; _obj.m_socketId = -1;
#endif
_obj.m_name = ""; _obj.m_name = "";
_obj.m_status = status::error; _obj.m_status = status::error;
m_fds[0] = _obj.m_fds[0];
#if 1
memset(_obj.m_fds, 0 , sizeof(_obj.m_fds));
#endif
} }
enet::Tcp::~Tcp() { enet::Tcp::~Tcp() {
unlink(); unlink();
} }
@@ -67,25 +76,31 @@ enet::Tcp::~Tcp() {
enet::Tcp& enet::Tcp::operator = (enet::Tcp&& _obj) { enet::Tcp& enet::Tcp::operator = (enet::Tcp&& _obj) {
unlink(); unlink();
m_socketId = _obj.m_socketId; m_socketId = _obj.m_socketId;
#ifdef __TARGET_OS__Windows
_obj.m_socketId = INVALID_SOCKET;
#else
_obj.m_socketId = -1; _obj.m_socketId = -1;
#endif
m_name = _obj.m_name; m_name = _obj.m_name;
_obj.m_name = ""; _obj.m_name = "";
m_status = _obj.m_status; m_status = _obj.m_status;
_obj.m_status = status::error; _obj.m_status = status::error;
m_fds[0] = _obj.m_fds[0];
#if 1
memset(_obj.m_fds, 0 , sizeof(_obj.m_fds));
#endif
return *this; return *this;
} }
bool enet::Tcp::unlink() { bool enet::Tcp::unlink() {
if (m_socketId >= 0) { if (m_socketId >= 0) {
ENET_INFO("Close socket (start)"); ENET_INFO("Close socket (start)");
#ifdef __TARGET_OS__Windows
shutdown(m_socketId, SD_BOTH);
closesocket(m_socketId);
m_socketId = INVALID_SOCKET;
#else
shutdown(m_socketId, SHUT_RDWR); shutdown(m_socketId, SHUT_RDWR);
close(m_socketId); close(m_socketId);
ENET_INFO("Close socket (done)");
m_socketId = -1; m_socketId = -1;
#endif
ENET_INFO("Close socket (done)");
} }
m_status = status::unlink; m_status = status::unlink;
return true; return true;
@@ -98,29 +113,36 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
return -1; return -1;
} }
int32_t size = -1; int32_t size = -1;
int nfds = 1;
fd_set sock;
// Initialize the timeout to 3 minutes. If no activity after 3 minutes this program will end. timeout value is based on milliseconds. // Initialize the timeout to 3 minutes. If no activity after 3 minutes this program will end. timeout value is based on milliseconds.
int timeout = (3 * 60 * 1000); struct timeval timeOutStruct;
// Call poll() and wait 3 minutes for it to complete. timeOutStruct.tv_sec = (3 * 60 * 1000);
int rc = poll(m_fds, nfds, timeout); timeOutStruct.tv_usec = 0;
FD_ZERO(&sock);
FD_SET(m_socketId,&sock);
int rc = select(m_socketId+1, &sock, NULL, NULL, &timeOutStruct);
// Check to see if the poll call failed. // Check to see if the poll call failed.
if (rc < 0) { if (rc < 0) {
ENET_ERROR(" poll() failed"); ENET_ERROR(" select() failed");
return-1; return -1;
} }
// Check to see if the 3 minute time out expired. // Check to see if the 3 minute time out expired.
if (rc == 0) { if (rc == 0) {
ENET_ERROR(" poll() timed out.\n"); ENET_ERROR(" select() timed out.");
return -2; return -2;
} }
if (!FD_ISSET(m_socketId, &sock)) {
ENET_ERROR(" select() id is not set...");
return -1;
}
bool closeConn = false; bool closeConn = false;
// Receive all incoming data on this socket before we loop back and call poll again. // Receive all incoming data on this socket before we loop back and call poll again.
// Receive data on this connection until the recv fails with EWOULDBLOCK. // Receive data on this connection until the recv fails with EWOULDBLOCK.
// If any other failure occurs, we will close the connection. // If any other failure occurs, we will close the connection.
{ {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
//ENET_DEBUG("Read on socketid = " << m_fds[0].fd ); rc = recv(m_socketId, (char *)_data, _maxLen, 0);
rc = recv(m_fds[0].fd, _data, _maxLen, 0);
} }
if (rc < 0) { if (rc < 0) {
if (errno != EWOULDBLOCK) { if (errno != EWOULDBLOCK) {
@@ -142,6 +164,7 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
ENET_DEBUG(" Set status at remote close ..."); ENET_DEBUG(" Set status at remote close ...");
m_status = status::linkRemoteClose; m_status = status::linkRemoteClose;
} }
//#endif
return size; return size;
} }
@@ -155,7 +178,7 @@ int32_t enet::Tcp::write(const void* _data, int32_t _len) {
int32_t size; int32_t size;
{ {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
size = ::write(m_socketId, _data, _len); size = ::send(m_socketId, (const char *)_data, _len, 0);
} }
if ( size != _len if ( size != _len
&& errno != 0) { && errno != 0) {

View File

@@ -5,19 +5,29 @@
*/ */
#pragma once #pragma once
#include <etk/types.h> #include <etk/types.hpp>
#include <poll.h>
#include <mutex> #include <mutex>
#ifdef __TARGET_OS__Windows
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
namespace enet { namespace enet {
class Tcp { class Tcp {
private: private:
#ifdef __TARGET_OS__Windows
SOCKET m_socketId; //!< socket Windows interface generic
#else
int32_t m_socketId; //!< socket linux interface generic int32_t m_socketId; //!< socket linux interface generic
struct pollfd m_fds[1]; #endif
std::mutex m_mutex; std::mutex m_mutex;
public: public:
Tcp(); Tcp();
#ifdef __TARGET_OS__Windows
Tcp(SOCKET _idSocket, const std::string& _name);
#else
Tcp(int32_t _idSocket, const std::string& _name); Tcp(int32_t _idSocket, const std::string& _name);
#endif
// move constructor // move constructor
Tcp(Tcp&& _obj); Tcp(Tcp&& _obj);
// Move operator; // Move operator;

View File

@@ -4,18 +4,22 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <enet/debug.h> #include <enet/debug.hpp>
#include <enet/Tcp.h> #include <enet/Tcp.hpp>
#include <enet/TcpClient.h> #include <enet/TcpClient.hpp>
#include <enet/enet.hpp>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <cerrno>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <cstring>
#include <etk/stdTools.h> #include <etk/stdTools.hpp>
#include <sys/socket.h>
#ifdef __TARGET_OS__Windows
#else
#include <netinet/in.h>
#include <netdb.h>
#endif
enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port, uint32_t _numberRetry) { enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port, uint32_t _numberRetry) {
std::string tmpname; std::string tmpname;
@@ -28,7 +32,86 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8
tmpname += etk::to_string(_ip4); tmpname += etk::to_string(_ip4);
return std::move(enet::connectTcpClient(tmpname, _port, _numberRetry)); return std::move(enet::connectTcpClient(tmpname, _port, _numberRetry));
} }
enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry) {
#ifdef __TARGET_OS__Windows
enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry) {
if (enet::isInit() == false) {
ENET_ERROR("Need call enet::init(...) before accessing to the socket");
return std::move(enet::Tcp());
}
SOCKET socketId = INVALID_SOCKET;
ENET_INFO("Start connection on " << _hostname << ":" << _port);
for(int32_t iii=0; iii<_numberRetry ;iii++) {
// open in Socket normal mode
socketId = socket(AF_INET, SOCK_STREAM, 0);
if (socketId < 0) {
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue;
}
ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << _numberRetry << ")");
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
struct addrinfo* result = nullptr;
std::string portValue = etk::to_string(_port);
int iResult = getaddrinfo(_hostname.c_str(), portValue.c_str(), &hints, &result);
if (iResult != 0) {
ENET_ERROR("getaddrinfo failed with error: " << iResult);
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue;
}
// Attempt to connect to an address until one succeeds
for(struct addrinfo* ptr=result;
ptr != nullptr;
ptr=ptr->ai_next) {
ENET_DEBUG(" find one ...");
// Create a SOCKET for connecting to server
socketId = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (socketId == INVALID_SOCKET) {
ENET_ERROR("socket failed with error: " << WSAGetLastError());
break;
}
// Connect to server.
iResult = connect(socketId, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
ENET_ERROR("socket connection failed with error: " << WSAGetLastError());
closesocket(socketId);
socketId = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (socketId == INVALID_SOCKET) {
ENET_ERROR("Unable to connect to server!");
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue;
} else {
break;
}
}
if (socketId == INVALID_SOCKET) {
ENET_ERROR("ERROR connecting ... (after all try)");
return std::move(enet::Tcp());
}
ENET_DEBUG("Connection done");
return std::move(enet::Tcp(socketId, _hostname + ":" + etk::to_string(_port)));
}
#else
#include <sys/socket.h>
enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry) {
if (enet::isInit() == false) {
ENET_ERROR("Need call enet::init(...) before accessing to the socket");
return std::move(enet::Tcp());
}
int32_t socketId = -1; int32_t socketId = -1;
ENET_INFO("Start connection on " << _hostname << ":" << _port); ENET_INFO("Start connection on " << _hostname << ":" << _port);
for(int32_t iii=0; iii<_numberRetry ;iii++) { for(int32_t iii=0; iii<_numberRetry ;iii++) {
@@ -36,7 +119,7 @@ enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, u
socketId = socket(AF_INET, SOCK_STREAM, 0); socketId = socket(AF_INET, SOCK_STREAM, 0);
if (socketId < 0) { if (socketId < 0) {
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno)); ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
usleep(200000); std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue; continue;
} }
ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << _numberRetry << ")"); ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << _numberRetry << ")");
@@ -44,7 +127,7 @@ enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, u
struct hostent* server = gethostbyname(_hostname.c_str()); struct hostent* server = gethostbyname(_hostname.c_str());
if (server == nullptr) { if (server == nullptr) {
ENET_ERROR("ERROR, no such host : " << _hostname); ENET_ERROR("ERROR, no such host : " << _hostname);
usleep(200000); std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue; continue;
} }
bzero((char *) &servAddr, sizeof(servAddr)); bzero((char *) &servAddr, sizeof(servAddr));
@@ -59,11 +142,15 @@ enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, u
&& errno != ECONNREFUSED) { && errno != ECONNREFUSED) {
ENET_ERROR("ERROR connecting on : errno=" << errno << "," << strerror(errno)); ENET_ERROR("ERROR connecting on : errno=" << errno << "," << strerror(errno));
} }
#ifdef __TARGET_OS__Windows
closesocket(socketId);
#else
close(socketId); close(socketId);
#endif
socketId = -1; socketId = -1;
} }
ENET_ERROR("ERROR connecting, maybe retry ... errno=" << errno << "," << strerror(errno)); ENET_ERROR("ERROR connecting, maybe retry ... errno=" << errno << "," << strerror(errno));
usleep(500000); std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue; continue;
} }
// if we are here ==> then the connextion is done corectly ... // if we are here ==> then the connextion is done corectly ...
@@ -75,5 +162,6 @@ enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, u
} }
ENET_DEBUG("Connection done"); ENET_DEBUG("Connection done");
return std::move(enet::Tcp(socketId, _hostname + ":" + etk::to_string(_port))); return std::move(enet::Tcp(socketId, _hostname + ":" + etk::to_string(_port)));
} }
#endif

View File

@@ -5,7 +5,7 @@
*/ */
#pragma once #pragma once
#include <enet/Tcp.h> #include <enet/Tcp.hpp>
namespace enet { namespace enet {
enet::Tcp connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port, uint32_t _numberRetry=5); enet::Tcp connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port, uint32_t _numberRetry=5);

View File

@@ -4,18 +4,26 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <enet/debug.h> #include <enet/debug.hpp>
#include <enet/Tcp.h> #include <enet/Tcp.hpp>
#include <enet/TcpServer.h> #include <enet/TcpServer.hpp>
#include <enet/enet.hpp>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <cerrno>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <cstring>
#include <etk/stdTools.h> #include <etk/stdTools.hpp>
#ifdef __TARGET_OS__Windows
#include <winsock2.h>
#include <ws2tcpip.h>
//https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms737889(v=vs.85).aspx
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#endif
enet::TcpServer::TcpServer() : enet::TcpServer::TcpServer() :
m_socketId(-1), m_socketId(-1),
@@ -54,7 +62,59 @@ void enet::TcpServer::setPort(uint16_t _port) {
m_port = _port; m_port = _port;
} }
bool enet::TcpServer::link() { #ifdef __TARGET_OS__Windows
bool enet::TcpServer::link() {
if (enet::isInit() == false) {
ENET_ERROR("Need call enet::init(...) before accessing to the socket");
return false;
}
ENET_INFO("Start connection on " << m_host << ":" << m_port);
struct addrinfo *result = nullptr;
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
std::string portValue = etk::to_string(m_port);
int iResult = getaddrinfo(nullptr, portValue.c_str(), &hints, &result);
if (iResult != 0) {
ENET_ERROR("getaddrinfo failed with error: " << iResult);
return 1;
}
// open in Socket normal mode
m_socketId = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (m_socketId == INVALID_SOCKET) {
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
freeaddrinfo(result);
return false;
}
// set the reuse of the socket if previously opened :
int sockOpt = 1;
if(setsockopt(m_socketId, SOL_SOCKET, SO_REUSEADDR, (const char*)&sockOpt, sizeof(int)) != 0) {
ENET_ERROR("ERROR while configuring socket re-use : errno=" << errno << "," << strerror(errno));
return false;
}
ENET_INFO("Start binding Socket ... (can take some time ...)");
if (bind(m_socketId, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
ENET_ERROR("ERROR on binding errno=" << WSAGetLastError());
freeaddrinfo(result);
closesocket(m_socketId);
m_socketId = INVALID_SOCKET;
return false;
}
return true;
}
#else
bool enet::TcpServer::link() {
if (enet::isInit() == false) {
ENET_ERROR("Need call enet::init(...) before accessing to the socket");
return false;
}
ENET_INFO("Start connection on " << m_host << ":" << m_port); ENET_INFO("Start connection on " << m_host << ":" << m_port);
// open in Socket normal mode // open in Socket normal mode
m_socketId = socket(AF_INET, SOCK_STREAM, 0); m_socketId = socket(AF_INET, SOCK_STREAM, 0);
@@ -77,24 +137,48 @@ bool enet::TcpServer::link() {
ENET_INFO("Start binding Socket ... (can take some time ...)"); ENET_INFO("Start binding Socket ... (can take some time ...)");
if (bind(m_socketId, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) { if (bind(m_socketId, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
ENET_ERROR("ERROR on binding errno=" << errno << "," << strerror(errno)); ENET_ERROR("ERROR on binding errno=" << errno << "," << strerror(errno));
#ifdef __TARGET_OS__Windows
closesocket(m_socketId);
m_socketId = INVALID_SOCKET;
#else
close(m_socketId); close(m_socketId);
m_socketId = -1; m_socketId = -1;
#endif
return false; return false;
} }
return true; return true;
} }
#endif
enet::Tcp enet::TcpServer::waitNext() { enet::Tcp enet::TcpServer::waitNext() {
if (enet::isInit() == false) {
ENET_ERROR("Need call enet::init(...) before accessing to the socket");
return std::move(enet::Tcp());
}
ENET_INFO("End binding Socket ... (start listen)"); ENET_INFO("End binding Socket ... (start listen)");
listen(m_socketId,1); // 1 is for the number of connection at the same time ... #ifdef __TARGET_OS__Windows
int ret = listen(m_socketId, SOMAXCONN);
if (ret == SOCKET_ERROR) {
ENET_ERROR("listen failed with error: " << WSAGetLastError());
return enet::Tcp();;
}
#else
listen(m_socketId, 1); // 1 is for the number of connection at the same time ...
#endif
ENET_INFO("End listen Socket ... (start accept)"); ENET_INFO("End listen Socket ... (start accept)");
struct sockaddr_in clientAddr; struct sockaddr_in clientAddr;
socklen_t clilen = sizeof(clientAddr); socklen_t clilen = sizeof(clientAddr);
int32_t socketIdClient = accept(m_socketId, (struct sockaddr *) &clientAddr, &clilen); int32_t socketIdClient = accept(m_socketId, (struct sockaddr *) &clientAddr, &clilen);
if (socketIdClient < 0) { if (socketIdClient < 0) {
ENET_ERROR("ERROR on accept errno=" << errno << "," << strerror(errno)); ENET_ERROR("ERROR on accept errno=" << errno << "," << strerror(errno));
#ifdef __TARGET_OS__Windows
closesocket(m_socketId);
m_socketId = INVALID_SOCKET;
#else
close(m_socketId); close(m_socketId);
m_socketId = -1; m_socketId = -1;
#endif
return enet::Tcp(); return enet::Tcp();
} }
ENET_INFO("End configuring Socket ... Find New one"); ENET_INFO("End configuring Socket ... Find New one");
@@ -103,10 +187,18 @@ enet::Tcp enet::TcpServer::waitNext() {
bool enet::TcpServer::unlink() { bool enet::TcpServer::unlink() {
#ifdef __TARGET_OS__Windows
if (m_socketId != INVALID_SOCKET) {
ENET_INFO(" close server socket");
closesocket(m_socketId);
m_socketId = INVALID_SOCKET;
}
#else
if (m_socketId >= 0) { if (m_socketId >= 0) {
ENET_INFO(" close server socket"); ENET_INFO(" close server socket");
close(m_socketId); close(m_socketId);
m_socketId = -1; m_socketId = -1;
} }
#endif
return true; return true;
} }

View File

@@ -4,15 +4,22 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#pragma once #pragma once
#include <enet/Tcp.hpp>
#ifdef __TARGET_OS__Windows
#include <poll.h> #else
#include <enet/Tcp.h> #include <poll.h>
#endif
namespace enet { namespace enet {
class TcpServer { class TcpServer {
private: private:
#ifdef __TARGET_OS__Windows
SOCKET m_socketId; //!< socket Windows interface generic
#else
int32_t m_socketId; //!< socket linux interface generic int32_t m_socketId; //!< socket linux interface generic
#if 1 #endif
#ifndef __TARGET_OS__Windows
struct pollfd m_fds[1]; struct pollfd m_fds[1];
#endif #endif
public: public:

View File

@@ -4,6 +4,6 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <enet/debug.h> #include <enet/debug.hpp>
#include <enet/Udp.h> #include <enet/Udp.hpp>

View File

@@ -4,15 +4,15 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <enet/debug.h> #include <enet/debug.hpp>
#include <enet/WebSocket.h> #include <enet/WebSocket.hpp>
#include <map> #include <map>
#include <etk/stdTools.h> #include <etk/stdTools.hpp>
#include <string.h> #include <cstring>
#include <random> #include <random>
#include <algue/base64.h> #include <algue/base64.hpp>
#include <algue/sha1.h> #include <algue/sha1.hpp>
#include <unistd.h>
namespace enet { namespace enet {
@@ -115,7 +115,7 @@ void enet::WebSocket::start(const std::string& _uri, const std::vector<std::stri
} }
m_interface->start(); m_interface->start();
if (m_interface->isServer() == false) { if (m_interface->isServer() == false) {
enet::HttpRequest req(enet::HTTPReqType::GET); enet::HttpRequest req(enet::HTTPReqType::HTTP_GET);
req.setProtocol(enet::HTTPProtocol::http_1_1); req.setProtocol(enet::HTTPProtocol::http_1_1);
req.setUri(_uri); req.setUri(_uri);
req.setKey("Upgrade", "websocket"); req.setKey("Upgrade", "websocket");
@@ -148,7 +148,7 @@ void enet::WebSocket::start(const std::string& _uri, const std::vector<std::stri
|| m_interface->isAlive() == false) { || m_interface->isAlive() == false) {
break; break;
} }
usleep(10000); std::this_thread::sleep_for(std::chrono::milliseconds(10));
timeout--; timeout--;
} }
if ( m_connectionValidate == false if ( m_connectionValidate == false
@@ -342,7 +342,7 @@ void enet::WebSocket::onReceiveRequest(const enet::HttpRequest& _data) {
return; return;
} }
_data.display(); _data.display();
if (_data.getType() != enet::HTTPReqType::GET) { if (_data.getType() != enet::HTTPReqType::HTTP_GET) {
enet::HttpAnswer answer(enet::HTTPAnswerCode::c400_badRequest, "support only GET"); enet::HttpAnswer answer(enet::HTTPAnswerCode::c400_badRequest, "support only GET");
answer.setProtocol(enet::HTTPProtocol::http_1_1); answer.setProtocol(enet::HTTPProtocol::http_1_1);
answer.setKey("Connection", "close"); answer.setKey("Connection", "close");

View File

@@ -5,8 +5,8 @@
*/ */
#pragma once #pragma once
#include <enet/Http.h> #include <enet/Http.hpp>
#include <ememory/memory.h> #include <ememory/memory.hpp>
#include <vector> #include <vector>
#include <map> #include <map>

View File

@@ -4,7 +4,7 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <enet/debug.h> #include <enet/debug.hpp>
int32_t enet::getLogId() { int32_t enet::getLogId() {
static int32_t g_val = elog::registerInstance("enet"); static int32_t g_val = elog::registerInstance("enet");

View File

@@ -5,7 +5,7 @@
*/ */
#pragma once #pragma once
#include <elog/log.h> #include <elog/log.hpp>
namespace enet { namespace enet {
int32_t getLogId(); int32_t getLogId();

54
enet/enet.cpp Normal file
View File

@@ -0,0 +1,54 @@
/** @file
* @author Edouard DUPIN
* @copyright 2014, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <enet/enet.hpp>
#include <enet/debug.hpp>
static bool& getInitSatatus() {
static bool isInit = false;
return isInit;
}
#ifdef __TARGET_OS__Windows
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
WSADATA wsaData;
#endif
void enet::init(int _argc, const char** _argv) {
for (int32_t iii=0; iii<_argc; ++iii) {
std::string value = _argv[iii];
if (etk::start_with(value, "--enet") == true) {
ENET_ERROR("Unknow parameter type: '" << value << "'");
}
}
if (getInitSatatus() == false) {
#ifdef __TARGET_OS__Windows
// Initialize Winsock
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
ENET_ERROR("WSAStartup failed with error: " << iResult);
}
#endif
getInitSatatus() = true;
}
}
void enet::unInit() {
if (getInitSatatus() == false) {
ENET_ERROR("Request UnInit of enent already done ...");
} else {
#ifdef __TARGET_OS__Windows
WSACleanup();
#endif
}
getInitSatatus() = false;
}
bool enet::isInit() {
return getInitSatatus();
}

View File

@@ -1,12 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2014, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <enet/Udp.h>
#include <enet/Tcp.h>
#include <enet/Http.h>
#include <enet/Ftp.h>

34
enet/enet.hpp Normal file
View File

@@ -0,0 +1,34 @@
/** @file
* @author Edouard DUPIN
* @copyright 2014, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <enet/Udp.hpp>
#include <enet/Tcp.hpp>
#include <enet/Http.hpp>
#include <enet/Ftp.hpp>
/**
* @brief Main esvg namespace
*/
namespace enet {
/**
* @brief Initialize enet
* @param[in] _argc Number of argument list
* @param[in] _argv List of arguments
*/
void init(int _argc, const char** _argv);
/**
* @brief un-Initialize enet
*/
void unInit();
/**
* @brief Check if the library is initialized
* @return bool value to chek if initialize ot not
*/
bool isInit();
}

View File

@@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.module as module import lutin.debug as debug
import lutin.tools as tools import lutin.tools as tools
@@ -24,14 +24,17 @@ def get_compagny_name():
def get_maintainer(): def get_maintainer():
return "authors.txt" return "authors.txt"
def create(target, module_name): def configure(target, my_module):
my_module = module.Module(__file__, module_name, get_type()) my_module.add_path(".")
my_module.add_path(tools.get_current_path(__file__), export=True) my_module.add_depend([
my_module.add_depend(['enet', 'gtest', 'test-debug']) 'enet',
'gtest',
'test-debug'
])
my_module.add_src_file([ my_module.add_src_file([
'test/main-client-http.cpp' 'test/main-client-http.cpp'
]) ])
return my_module return True

View File

@@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.module as module import lutin.debug as debug
import lutin.tools as tools import lutin.tools as tools
@@ -24,14 +24,17 @@ def get_compagny_name():
def get_maintainer(): def get_maintainer():
return "authors.txt" return "authors.txt"
def create(target, module_name): def configure(target, my_module):
my_module = module.Module(__file__, module_name, get_type()) my_module.add_path(".")
my_module.add_path(tools.get_current_path(__file__), export=True) my_module.add_depend([
my_module.add_depend(['enet', 'gtest', 'test-debug']) 'enet',
'gtest',
'test-debug'
])
my_module.add_src_file([ my_module.add_src_file([
'test/main-client-websocket.cpp' 'test/main-client-websocket.cpp'
]) ])
return my_module return True

View File

@@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.module as module import lutin.debug as debug
import lutin.tools as tools import lutin.tools as tools
@@ -24,14 +24,17 @@ def get_compagny_name():
def get_maintainer(): def get_maintainer():
return "authors.txt" return "authors.txt"
def create(target, module_name): def configure(target, my_module):
my_module = module.Module(__file__, module_name, get_type()) my_module.add_path(".")
my_module.add_path(tools.get_current_path(__file__), export=True) my_module.add_depend([
my_module.add_depend(['enet', 'gtest', 'test-debug']) 'enet',
'gtest',
'test-debug'
])
my_module.add_src_file([ my_module.add_src_file([
'test/main-client.cpp' 'test/main-client.cpp'
]) ])
return my_module return True

View File

@@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.module as module import lutin.debug as debug
import lutin.tools as tools import lutin.tools as tools
@@ -24,14 +24,17 @@ def get_compagny_name():
def get_maintainer(): def get_maintainer():
return "authors.txt" return "authors.txt"
def create(target, module_name): def configure(target, my_module):
my_module = module.Module(__file__, module_name, get_type()) my_module.add_path(".")
my_module.add_path(tools.get_current_path(__file__), export=True) my_module.add_depend([
my_module.add_depend(['enet', 'gtest', 'test-debug']) 'enet',
'gtest',
'test-debug'
])
my_module.add_src_file([ my_module.add_src_file([
'test/main-server-http.cpp' 'test/main-server-http.cpp'
]) ])
return my_module return True

View File

@@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.module as module import lutin.debug as debug
import lutin.tools as tools import lutin.tools as tools
@@ -24,14 +24,17 @@ def get_compagny_name():
def get_maintainer(): def get_maintainer():
return "authors.txt" return "authors.txt"
def create(target, module_name): def configure(target, my_module):
my_module = module.Module(__file__, module_name, get_type()) my_module.add_path(".")
my_module.add_path(tools.get_current_path(__file__), export=True) my_module.add_depend([
my_module.add_depend(['enet', 'gtest', 'test-debug']) 'enet',
'gtest',
'test-debug'
])
my_module.add_src_file([ my_module.add_src_file([
'test/main-server-websocket.cpp' 'test/main-server-websocket.cpp'
]) ])
return my_module return True

View File

@@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.module as module import lutin.debug as debug
import lutin.tools as tools import lutin.tools as tools
@@ -24,14 +24,17 @@ def get_compagny_name():
def get_maintainer(): def get_maintainer():
return "authors.txt" return "authors.txt"
def create(target, module_name): def configure(target, my_module):
my_module = module.Module(__file__, module_name, get_type()) my_module.add_path(".")
my_module.add_path(tools.get_current_path(__file__), export=True) my_module.add_depend([
my_module.add_depend(['enet', 'gtest', 'test-debug']) 'enet',
'gtest',
'test-debug'
])
my_module.add_src_file([ my_module.add_src_file([
'test/main-server.cpp' 'test/main-server.cpp'
]) ])
return my_module return True

View File

@@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.module as module import lutin.debug as debug
import lutin.tools as tools import lutin.tools as tools
@@ -24,16 +24,17 @@ def get_maintainer():
def get_version(): def get_version():
return "version.txt" return "version.txt"
def create(target, module_name): def configure(target, my_module):
my_module = module.Module(__file__, module_name, get_type()) my_module.add_depend([
my_module.add_depend(['etk', 'ememory', 'algue']) 'etk',
my_module.add_src_file([ 'ememory',
'enet/debug.cpp' 'algue',
'ethread'
]) ])
my_module.add_path(tools.get_current_path(__file__)) my_module.add_path(".")
if "Windows" in target.get_type():
return my_module
my_module.add_src_file([ my_module.add_src_file([
'enet/debug.cpp',
'enet/enet.cpp',
'enet/Udp.cpp', 'enet/Udp.cpp',
'enet/Tcp.cpp', 'enet/Tcp.cpp',
'enet/TcpServer.cpp', 'enet/TcpServer.cpp',
@@ -43,16 +44,19 @@ def create(target, module_name):
'enet/WebSocket.cpp', 'enet/WebSocket.cpp',
]) ])
my_module.add_header_file([ my_module.add_header_file([
'enet/debug.h', 'enet/enet.hpp',
'enet/Udp.h', 'enet/debug.hpp',
'enet/Tcp.h', 'enet/Udp.hpp',
'enet/TcpServer.h', 'enet/Tcp.hpp',
'enet/TcpClient.h', 'enet/TcpServer.hpp',
'enet/Http.h', 'enet/TcpClient.hpp',
'enet/Ftp.h', 'enet/Http.hpp',
'enet/WebSocket.h', 'enet/Ftp.hpp',
'enet/WebSocket.hpp',
]) ])
return my_module if "Windows" in target.get_type():
my_module.add_depend("ws2");
return True

View File

@@ -4,14 +4,15 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <test-debug/debug.h> #include <test-debug/debug.hpp>
#include <enet/Tcp.h> #include <enet/enet.hpp>
#include <enet/TcpClient.h> #include <enet/Tcp.hpp>
#include <enet/Http.h> #include <enet/TcpClient.hpp>
#include <etk/etk.h> #include <enet/Http.hpp>
#include <etk/etk.hpp>
#include <etk/stdTools.hpp>
#include <etk/stdTools.h>
#include <unistd.h>
namespace appl { namespace appl {
void onReceiveData(std::vector<uint8_t>& _data) { void onReceiveData(std::vector<uint8_t>& _data) {
@@ -22,6 +23,7 @@ namespace appl {
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@@ -35,7 +37,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test HTTP client =="); TEST_INFO("== Test HTTP client ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
// connect on TCP server: // connect on TCP server:
enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345)); enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345));
// TODO : Check if connection is valid ... // TODO : Check if connection is valid ...
@@ -47,16 +48,12 @@ int main(int _argc, const char *_argv[]) {
// start http connection (the actual state is just TCP start ...) // start http connection (the actual state is just TCP start ...)
connection.start(); connection.start();
enet::HttpRequest req(enet::HTTPReqType::GET); enet::HttpRequest req(enet::HTTPReqType::HTTP_GET);
req.setUri("plop.txt"); req.setUri("plop.txt");
connection.setHeader(req); connection.setHeader(req);
while (connection.isAlive() == true) { while (connection.isAlive() == true) {
usleep(100000); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@@ -4,15 +4,16 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <test-debug/debug.h> #include <test-debug/debug.hpp>
#include <enet/Tcp.h> #include <enet/enet.hpp>
#include <enet/TcpClient.h> #include <enet/Tcp.hpp>
#include <enet/Http.h> #include <enet/TcpClient.hpp>
#include <enet/WebSocket.h> #include <enet/Http.hpp>
#include <etk/etk.h> #include <enet/WebSocket.hpp>
#include <etk/etk.hpp>
#include <etk/stdTools.hpp>
#include <etk/stdTools.h>
#include <unistd.h>
namespace appl { namespace appl {
void onReceiveData(std::vector<uint8_t>& _data, bool _isString) { void onReceiveData(std::vector<uint8_t>& _data, bool _isString) {
@@ -29,6 +30,7 @@ namespace appl {
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@@ -42,7 +44,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test WebSocket client =="); TEST_INFO("== Test WebSocket client ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
// connect on TCP server: // connect on TCP server:
enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345)); enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345));
// TODO : Check if connection is valid ... // TODO : Check if connection is valid ...
@@ -65,12 +66,8 @@ int main(int _argc, const char *_argv[]) {
int32_t timeout = 20; int32_t timeout = 20;
while (connection.isAlive() == true while (connection.isAlive() == true
&& timeout > 0) { && timeout > 0) {
usleep(100000); std::this_thread::sleep_for(std::chrono::milliseconds(100));
timeout--; timeout--;
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@@ -4,16 +4,18 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <test-debug/debug.h> #include <test-debug/debug.hpp>
#include <enet/Tcp.h> #include <enet/enet.hpp>
#include <enet/TcpClient.h> #include <enet/Tcp.hpp>
#include <enet/Http.h> #include <enet/TcpClient.hpp>
#include <etk/etk.h> #include <enet/Http.hpp>
#include <etk/etk.hpp>
#include <etk/stdTools.h> #include <iostream>
#include <etk/stdTools.hpp>
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@@ -27,7 +29,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test TCP client =="); TEST_INFO("== Test TCP client ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
// client mode ... // client mode ...
// connect on TCP server: // connect on TCP server:
enet::Tcp connection = std::move(enet::connectTcpClient("127.0.0.1", 12345)); enet::Tcp connection = std::move(enet::connectTcpClient("127.0.0.1", 12345));
@@ -37,12 +38,18 @@ int main(int _argc, const char *_argv[]) {
return -1; return -1;
} }
int32_t iii = 0; int32_t iii = 0;
int32_t delay = 200;
while ( connection.getConnectionStatus() == enet::Tcp::status::link while ( connection.getConnectionStatus() == enet::Tcp::status::link
&& iii<10000) { && iii<10000) {
char data[1024]; char data[1024];
int32_t len = connection.read(data, 1024); int32_t len = connection.read(data, 1024);
TEST_INFO("read len=" << len << " data='" << data << "'"); TEST_INFO("read len=" << len << " data='" << data << "'");
//if (data[len-1] == '2') { //if (data[len-1] == '2') {
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
delay--;
if (delay == 0) {
delay = 500;
}
int32_t lenWrite = connection.write("get pair value"); int32_t lenWrite = connection.write("get pair value");
TEST_INFO("write len=" << lenWrite); TEST_INFO("write len=" << lenWrite);
//} //}
@@ -59,8 +66,5 @@ int main(int _argc, const char *_argv[]) {
TEST_ERROR("can not unlink to the socket..."); TEST_ERROR("can not unlink to the socket...");
return -1; return -1;
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@@ -4,14 +4,15 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <test-debug/debug.h> #include <test-debug/debug.hpp>
#include <enet/Tcp.h> #include <enet/enet.hpp>
#include <enet/Http.h> #include <enet/Tcp.hpp>
#include <enet/TcpServer.h> #include <enet/Http.hpp>
#include <etk/etk.h> #include <enet/TcpServer.hpp>
#include <etk/etk.hpp>
#include <unistd.h>
#include <etk/stdTools.h> #include <etk/stdTools.hpp>
namespace appl { namespace appl {
void onReceiveData(enet::HttpServer* _interface, std::vector<uint8_t>& _data) { void onReceiveData(enet::HttpServer* _interface, std::vector<uint8_t>& _data) {
TEST_INFO("Receive Datas : " << _data.size() << " bytes"); TEST_INFO("Receive Datas : " << _data.size() << " bytes");
@@ -19,7 +20,7 @@ namespace appl {
void onReceiveHeader(enet::HttpServer* _interface, const enet::HttpRequest& _data) { void onReceiveHeader(enet::HttpServer* _interface, const enet::HttpRequest& _data) {
TEST_INFO("Receive Header data:"); TEST_INFO("Receive Header data:");
_data.display(); _data.display();
if (_data.getType() == enet::HTTPReqType::GET) { if (_data.getType() == enet::HTTPReqType::HTTP_GET) {
if (_data.getUri() == "plop.txt") { if (_data.getUri() == "plop.txt") {
enet::HttpAnswer answer(enet::HTTPAnswerCode::c200_ok); enet::HttpAnswer answer(enet::HTTPAnswerCode::c200_ok);
std::string data = "<html><head></head></body>coucou</body></html>"; std::string data = "<html><head></head></body>coucou</body></html>";
@@ -39,6 +40,7 @@ namespace appl {
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@@ -52,7 +54,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test HTTP server =="); TEST_INFO("== Test HTTP server ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
//Wait on TCP connection: //Wait on TCP connection:
enet::TcpServer interface; enet::TcpServer interface;
// Configure server interface: // Configure server interface:
@@ -81,7 +82,7 @@ int main(int _argc, const char *_argv[]) {
connection.start(); connection.start();
while (connection.isAlive() == true) { while (connection.isAlive() == true) {
usleep(100000); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
@@ -112,8 +113,5 @@ int main(int _argc, const char *_argv[]) {
} }
TEST_INFO("data : " << connection.dataString()); TEST_INFO("data : " << connection.dataString());
*/ */
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@@ -4,15 +4,16 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <test-debug/debug.h> #include <test-debug/debug.hpp>
#include <enet/Tcp.h> #include <enet/enet.hpp>
#include <enet/Http.h> #include <enet/Tcp.hpp>
#include <enet/WebSocket.h> #include <enet/Http.hpp>
#include <enet/TcpServer.h> #include <enet/WebSocket.hpp>
#include <etk/etk.h> #include <enet/TcpServer.hpp>
#include <etk/etk.hpp>
#include <unistd.h>
#include <etk/stdTools.h> #include <etk/stdTools.hpp>
namespace appl { namespace appl {
void onReceiveData(enet::WebSocket* _interface, std::vector<uint8_t>& _data, bool _isString) { void onReceiveData(enet::WebSocket* _interface, std::vector<uint8_t>& _data, bool _isString) {
TEST_INFO("Receive Datas : " << _data.size() << " bytes"); TEST_INFO("Receive Datas : " << _data.size() << " bytes");
@@ -42,6 +43,7 @@ namespace appl {
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@@ -55,7 +57,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test WebSocket server =="); TEST_INFO("== Test WebSocket server ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
//Wait on TCP connection: //Wait on TCP connection:
enet::TcpServer interface; enet::TcpServer interface;
// Configure server interface: // Configure server interface:
@@ -84,10 +85,7 @@ int main(int _argc, const char *_argv[]) {
connection.start(); connection.start();
while (connection.isAlive() == true) { while (connection.isAlive() == true) {
usleep(100000); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@@ -4,16 +4,18 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <test-debug/debug.h> #include <test-debug/debug.hpp>
#include <enet/Tcp.h> #include <enet/enet.hpp>
#include <enet/Http.h> #include <enet/Tcp.hpp>
#include <etk/etk.h> #include <enet/Http.hpp>
#include <enet/TcpServer.h> #include <etk/etk.hpp>
#include <enet/TcpServer.hpp>
#include <etk/stdTools.h> #include <etk/stdTools.hpp>
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@@ -27,12 +29,11 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test TCP server =="); TEST_INFO("== Test TCP server ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
//Wait on TCP connection: //Wait on TCP connection:
enet::TcpServer interface; enet::TcpServer interface;
// Configure server interface: // Configure server interface:
interface.setHostNane("127.0.0.1"); interface.setHostNane("127.0.0.1");
interface.setPort(31235); interface.setPort(12345);
// Start listening ... // Start listening ...
interface.link(); interface.link();
// Wait a new connection .. // Wait a new connection ..
@@ -62,8 +63,5 @@ int main(int _argc, const char *_argv[]) {
TEST_ERROR("can not unlink to the socket..."); TEST_ERROR("can not unlink to the socket...");
return -1; return -1;
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@@ -1 +1 @@
0.3.0 0.4.0