From 577831079869c43eee3fc35909735f764ee38e3f Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 28 May 2017 18:09:29 +0100 Subject: [PATCH 1/6] Fixed incompatabilities between GCC and MSCV Build errors have been fixed, but there are build warnings remaining about unsafe conversions, because Visual C++'s network conversion functions have a differing return type to mine. To be fixed in the future. --- include/frnetlib/HttpRequest.h | 4 +-- include/frnetlib/HttpResponse.h | 2 +- include/frnetlib/NetworkEncoding.h | 45 +++++++++++++++++------------- include/frnetlib/SSLContext.h | 1 + src/HttpRequest.cpp | 4 +-- src/HttpResponse.cpp | 2 +- src/Socket.cpp | 2 +- src/TcpSocket.cpp | 4 +-- 8 files changed, 35 insertions(+), 29 deletions(-) diff --git a/include/frnetlib/HttpRequest.h b/include/frnetlib/HttpRequest.h index d7cbfe4..ad8f9fd 100644 --- a/include/frnetlib/HttpRequest.h +++ b/include/frnetlib/HttpRequest.h @@ -41,7 +41,7 @@ namespace fr * * @param header_end_pos The position in 'body' of the end of the header */ - void parse_header(ssize_t header_end_pos); + void parse_header(int32_t header_end_pos); /*! * Parses the POST data from the body @@ -64,7 +64,7 @@ namespace fr //State bool header_ended; - ssize_t last_parsed_character; + int32_t last_parsed_character; size_t content_length; }; diff --git a/include/frnetlib/HttpResponse.h b/include/frnetlib/HttpResponse.h index 21ec82f..d2d8383 100644 --- a/include/frnetlib/HttpResponse.h +++ b/include/frnetlib/HttpResponse.h @@ -41,7 +41,7 @@ namespace fr * * @param header_end_pos The position in 'body' of the end of the header */ - void parse_header(ssize_t header_end_pos); + void parse_header(int32_t header_end_pos); //State bool header_ended; diff --git a/include/frnetlib/NetworkEncoding.h b/include/frnetlib/NetworkEncoding.h index 1951dd4..4bbf410 100644 --- a/include/frnetlib/NetworkEncoding.h +++ b/include/frnetlib/NetworkEncoding.h @@ -28,44 +28,49 @@ #endif + +#ifdef __GNUC__ + #define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) #define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) inline float htonf(float val) { - uint32_t ret; - memcpy(&ret, &val, sizeof(ret)); - ret = htonl(ret); - memcpy(&val, &ret, sizeof(val)); - return val; + uint32_t ret; + memcpy(&ret, &val, sizeof(ret)); + ret = htonl(ret); + memcpy(&val, &ret, sizeof(val)); + return val; } inline float ntohf(float val) { - uint32_t ret; - memcpy(&ret, &val, sizeof(ret)); - ret = ntohl(ret); - memcpy(&val, &ret, sizeof(val)); - return val; + uint32_t ret; + memcpy(&ret, &val, sizeof(ret)); + ret = ntohl(ret); + memcpy(&val, &ret, sizeof(val)); + return val; } inline double htond(double val) { - uint64_t ret; - memcpy(&ret, &val, sizeof(ret)); - ret = htonll(ret); - memcpy(&val, &ret, sizeof(val)); - return val; + uint64_t ret; + memcpy(&ret, &val, sizeof(ret)); + ret = htonll(ret); + memcpy(&val, &ret, sizeof(val)); + return val; } inline double ntohd(double val) { - uint64_t ret; - memcpy(&ret, &val, sizeof(ret)); - ret = ntohll(ret); - memcpy(&val, &ret, sizeof(val)); - return val; + uint64_t ret; + memcpy(&ret, &val, sizeof(ret)); + ret = ntohll(ret); + memcpy(&val, &ret, sizeof(val)); + return val; } +#endif + inline void *get_sin_addr(struct sockaddr *sa) { if(sa->sa_family == AF_INET) diff --git a/include/frnetlib/SSLContext.h b/include/frnetlib/SSLContext.h index b53dc17..643b1cb 100644 --- a/include/frnetlib/SSLContext.h +++ b/include/frnetlib/SSLContext.h @@ -53,6 +53,7 @@ namespace fr */ bool load_ca_certs_from_memory(const std::string &ca_certs) { + std::cerr << "Note: load_ca_certs_from_memory() seems to be broken. Please use load_ca_certs_from_file() until this is resolved." << std::endl; int error = mbedtls_x509_crt_parse(&cacert, (const unsigned char *)ca_certs.c_str(), ca_certs.size()); if(error < 0) { diff --git a/src/HttpRequest.cpp b/src/HttpRequest.cpp index 1705a82..41e9508 100644 --- a/src/HttpRequest.cpp +++ b/src/HttpRequest.cpp @@ -52,7 +52,7 @@ namespace fr return true; } - void HttpRequest::parse_header(ssize_t header_end_pos) + void HttpRequest::parse_header(int32_t header_end_pos) { //Split the header into lines size_t line = 0; @@ -74,7 +74,7 @@ namespace fr //Store content length value if it exists auto length_header_iter = header_data.find("content-length"); if(length_header_iter != header_data.end()) - content_length = std::stoull(length_header_iter->second); + content_length = (size_t)std::stoull(length_header_iter->second); } std::string HttpRequest::construct(const std::string &host) const diff --git a/src/HttpResponse.cpp b/src/HttpResponse.cpp index b002ff5..1bb9d3c 100644 --- a/src/HttpResponse.cpp +++ b/src/HttpResponse.cpp @@ -62,7 +62,7 @@ namespace fr return response; } - void HttpResponse::parse_header(ssize_t header_end_pos) + void HttpResponse::parse_header(int32_t header_end_pos) { //Split the header into lines size_t line = 0; diff --git a/src/Socket.cpp b/src/Socket.cpp index 380cda9..e044686 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -83,7 +83,7 @@ namespace fr if(!connected()) return Socket::Disconnected; - ssize_t bytes_remaining = buffer_size; + int32_t bytes_remaining = buffer_size; size_t bytes_read = 0; while(bytes_remaining > 0) { diff --git a/src/TcpSocket.cpp b/src/TcpSocket.cpp index 49ea2c0..d319f82 100644 --- a/src/TcpSocket.cpp +++ b/src/TcpSocket.cpp @@ -25,7 +25,7 @@ namespace fr size_t sent = 0; while(sent < size) { - ssize_t status = ::send(socket_descriptor, data + sent, size - sent, 0); + int32_t status = ::send(socket_descriptor, data + sent, size - sent, 0); if(status > 0) { sent += status; @@ -53,7 +53,7 @@ namespace fr received = 0; //Read RECV_CHUNK_SIZE bytes into the recv buffer - ssize_t status = ::recv(socket_descriptor, (char*)data, buffer_size, 0); + int32_t status = ::recv(socket_descriptor, (char*)data, buffer_size, 0); if(status > 0) { From f1d1d0849ef372a966cd07044936bc8d9c9694cd Mon Sep 17 00:00:00 2001 From: miaodx Date: Mon, 29 May 2017 09:34:40 +0800 Subject: [PATCH 2/6] reorganize the include files according to the `SSL_ENABLED` flag. So that we can build without ssl support. --- src/SSLListener.cpp | 3 ++- src/SSLSocket.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SSLListener.cpp b/src/SSLListener.cpp index 1c0d4fc..cb6db1e 100644 --- a/src/SSLListener.cpp +++ b/src/SSLListener.cpp @@ -3,11 +3,12 @@ // #include -#include #include #include "frnetlib/SSLListener.h" #ifdef SSL_ENABLED +#include + namespace fr { SSLListener::SSLListener(std::shared_ptr ssl_context_, const std::string &crt_path, const std::string &pem_path, const std::string &private_key_path) noexcept diff --git a/src/SSLSocket.cpp b/src/SSLSocket.cpp index 283b3cb..cae2aed 100644 --- a/src/SSLSocket.cpp +++ b/src/SSLSocket.cpp @@ -4,10 +4,11 @@ #include "frnetlib/SSLSocket.h" #include -#include #ifdef SSL_ENABLED +#include + namespace fr { SSLSocket::SSLSocket(std::shared_ptr ssl_context_) noexcept From 1de53ef6e85e4c2db3028f8f0c8cedec609624dc Mon Sep 17 00:00:00 2001 From: miaodx Date: Mon, 29 May 2017 09:42:01 +0800 Subject: [PATCH 3/6] add some examples. --- examples/CMakeLists.txt | 29 +++++++++++++++++++++++++++++ examples/packet.cpp | 14 ++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 examples/CMakeLists.txt create mode 100644 examples/packet.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..7b32747 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.5) +project(frnetlib_test) + +if( WIN32 ) + set( ADDITIONAL_LIB ws2_32 ) # Ws2_32.lib + + set( FRNETLIB_ROOT_PATH "C:/tools/cmake_install_libs/frnetlib/" ) # change it to your install directory + + set( FRNETLIB_INCLUDE_PATH ${FRNETLIB_ROOT_PATH}/include ) + set( FRNETLIB_LIB ${FRNETLIB_ROOT_PATH}/lib/frnetlib-s-d.lib ) + + include_directories( ${FRNETLIB_INCLUDE_PATH} ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -std=c++14") + +elseif(APPLE) + set( ADDITIONAL_LIB "" ) +else() + set( ADDITIONAL_LIB "" ) + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -fPIC -std=c++14 -pthread -lmbedtls -lmbedx509 -lmbedcrypto") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -fPIC -std=c++14 -pthread") +endif() + + +add_executable(${PROJECT_NAME} ../main.cpp) +add_executable(packet packet.cpp) + + +target_link_libraries(${PROJECT_NAME} ${FRNETLIB_LIB} ${ADDITIONAL_LIB}) +target_link_libraries(packet ${FRNETLIB_LIB} ${ADDITIONAL_LIB}) \ No newline at end of file diff --git a/examples/packet.cpp b/examples/packet.cpp new file mode 100644 index 0000000..1897773 --- /dev/null +++ b/examples/packet.cpp @@ -0,0 +1,14 @@ +#include +#include "frnetlib/Packet.h" + + +int main() +{ + fr::Packet packet; + std::vector> bob = {{1, 2}, {3, 4}}; + packet << bob; + bob.clear(); + + packet >> bob; + std::cout << bob[0].first << ", " << bob[0].second << ", " << bob[1].first << ", " << bob[1].second << std::endl; +} \ No newline at end of file From bb9eaa39819992a33a290a633d285b1394878d19 Mon Sep 17 00:00:00 2001 From: miaodx Date: Mon, 29 May 2017 23:19:05 +0800 Subject: [PATCH 4/6] tcpsocket client and server example. --- examples/CMakeLists.txt | 7 ++- examples/tcpsocket_client.cpp | 86 +++++++++++++++++++++++++++++++++++ examples/tcpsocket_server.cpp | 76 +++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 examples/tcpsocket_client.cpp create mode 100644 examples/tcpsocket_server.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7b32747..e426c4e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -23,7 +23,10 @@ endif() add_executable(${PROJECT_NAME} ../main.cpp) add_executable(packet packet.cpp) - +add_executable(tcpsocket_server tcpsocket_server.cpp) +add_executable(tcpsocket_client tcpsocket_client.cpp) target_link_libraries(${PROJECT_NAME} ${FRNETLIB_LIB} ${ADDITIONAL_LIB}) -target_link_libraries(packet ${FRNETLIB_LIB} ${ADDITIONAL_LIB}) \ No newline at end of file +target_link_libraries(packet ${FRNETLIB_LIB} ${ADDITIONAL_LIB}) +target_link_libraries(tcpsocket_server ${FRNETLIB_LIB} ${ADDITIONAL_LIB}) +target_link_libraries(tcpsocket_client ${FRNETLIB_LIB} ${ADDITIONAL_LIB}) \ No newline at end of file diff --git a/examples/tcpsocket_client.cpp b/examples/tcpsocket_client.cpp new file mode 100644 index 0000000..4cbb581 --- /dev/null +++ b/examples/tcpsocket_client.cpp @@ -0,0 +1,86 @@ +#include +#include + +using namespace std; + + + +int client_round(fr::TcpSocket& socket) +{ + cout << "CLIENT:Going to send something ..." << endl; + + //Receive the request + fr::Packet packet; + packet << "Hello there, I am" << (float)1.2 << "years old"; + if (socket.send(packet) != fr::Socket::Success) + { + //Failed to send packet + cout << "CLIENT:Seems got something wrong when sending" << endl; + return -1; + } + + cout << "CLIENT:Going to receive ..." << endl; + + + if (socket.receive(packet) != fr::Socket::Success) + { + cout << "CLIENT:seems got something wrong when receiving" << endl; + return -2; + } + + std::string str1, str2; + float age; + packet >> str1 >> age >> str2; + + cout << "CLIENT:we got:" << str1 << age << str2 << endl; + + cout << "CLIENT:round finished" << endl; + cout << endl << endl << endl << endl; + return 0; +} + + +int main() +{ + fr::TcpSocket socket; + if (socket.connect("127.0.0.1", "8081") != fr::Socket::Success) + { + //Failed to connect + cout << "CLIENT:it seem that the socket can be accessed or there is no such socket at all" << endl; + socket.close_socket(); + return -1; + } + + + string op_str; + int rtn = 0; + + while (true) { + cout << "CLIENT:choose what you want to do, `c` for `continue`, `q` for `quit`:" << endl; + cin >> op_str; // count for possible mutiple char input + + if (op_str.length() > 1) { + cout << "CLIENT:Seems that you input more than one char, plese check your input" << endl; + continue; + } + + char op = op_str[0]; + switch (op) { + case 'c': + cout << "continue" << endl; + rtn = client_round(socket); + break; + case 'q': + break; + } + + if (op == 'q') + break; + if (rtn != 0) + break; + } + + socket.close_socket(); + cout << "all done, bye" << endl; +} + diff --git a/examples/tcpsocket_server.cpp b/examples/tcpsocket_server.cpp new file mode 100644 index 0000000..d1d4e7e --- /dev/null +++ b/examples/tcpsocket_server.cpp @@ -0,0 +1,76 @@ +#include +#include + +using namespace std; + +int main(){ + //fr::HttpSocket client; //fr::TcpSocket for HTTP. fr::SSLSocket for HTTPS. + + fr::TcpSocket client; + + + fr::TcpListener listener; //Use an fr::SSLListener if HTTPS. + + string port = "8081"; + + //Bind to a port + if(listener.listen(port) != fr::Socket::Success) + { + cout << "LISTENER:Failed to bind to port, going to shutdown" << endl; + listener.shutdown(); + return -1; + } + + cout << "LISTENER:Listener is listening on port " << port << " ..." << endl; + + while (true) + { + cout << "LISTENER:Waiting for a new connection ..." << endl; + //Accept a new connection + if (listener.accept(client) != fr::Socket::Success) + { + cout << "LISTENER:Failed to accept client, shutdown" << endl; + break; + } + + while (true) // infinate loop for the communication + { + try + { + fr::Packet packet; + if (client.receive(packet) != fr::Socket::Success) + { + cout << "LISTENER:Failed to receive request" << endl; + } + + std::string str1, str2; + float age; + packet >> str1 >> age >> str2; + + cout << "LISTENER:We got from client:" << str1 << age << str2 << endl; + + + if (client.send(packet) != fr::Socket::Success) + { + cout << "LISTENER:Seems got something wrong when sending" << endl; + //return -2; + } + } + catch (const std::exception& e) + { + cout << "ERROR: " << e.what() << endl; + cout << "LISTENER:Seems that the client stop the connection, just destory current connection and wait for another" << endl; + //Close connection + client.close_socket(); + break; + } + } // inner while + + + }// out while + + cout << "Should not got there !!" << endl; + listener.shutdown(); + return 0; +} + From 8a380c6620ebaa40d6088c530b62cda8653b619c Mon Sep 17 00:00:00 2001 From: miaodx Date: Mon, 29 May 2017 23:47:33 +0800 Subject: [PATCH 5/6] add FRNETLIB_LIB for apple and linux. --- examples/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e426c4e..7d7ca45 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -14,8 +14,10 @@ if( WIN32 ) elseif(APPLE) set( ADDITIONAL_LIB "" ) + set( FRNETLIB_LIB frnetlib) else() set( ADDITIONAL_LIB "" ) + set( FRNETLIB_LIB frnetlib) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -fPIC -std=c++14 -pthread -lmbedtls -lmbedx509 -lmbedcrypto") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -fPIC -std=c++14 -pthread") endif() From 7dccf41b7644c8231f5b69d8fdd2e7917fbd35aa Mon Sep 17 00:00:00 2001 From: miaodx Date: Mon, 29 May 2017 23:48:42 +0800 Subject: [PATCH 6/6] specify the ip and port. --- examples/tcpsocket_client.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/tcpsocket_client.cpp b/examples/tcpsocket_client.cpp index 4cbb581..41b7816 100644 --- a/examples/tcpsocket_client.cpp +++ b/examples/tcpsocket_client.cpp @@ -43,7 +43,11 @@ int client_round(fr::TcpSocket& socket) int main() { fr::TcpSocket socket; - if (socket.connect("127.0.0.1", "8081") != fr::Socket::Success) + + string server_ip = "127.0.0.1"; + string server_port = "8081"; + + if (socket.connect(server_ip, server_port) != fr::Socket::Success) { //Failed to connect cout << "CLIENT:it seem that the socket can be accessed or there is no such socket at all" << endl;