Skip to content

Commit

Permalink
Added TCP client module
Browse files Browse the repository at this point in the history
  • Loading branch information
yan9a committed Apr 30, 2024
1 parent b67a909 commit 3bbe875
Show file tree
Hide file tree
Showing 19 changed files with 753 additions and 135 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ ${PROJECT_SOURCE_DIR}/src/ceSerial.cpp
${PROJECT_SOURCE_DIR}/src/ceWxTmr.cpp
${PROJECT_SOURCE_DIR}/src/ceUDP.cpp
${PROJECT_SOURCE_DIR}/src/ceTcpServer.cpp
${PROJECT_SOURCE_DIR}/src/ceTcpClient.cpp
${PROJECT_SOURCE_DIR}/src/ceMisc.cpp
${PROJECT_SOURCE_DIR}/src/ceFrame.cpp
${PROJECT_SOURCE_DIR}/src/ceFraChecksum.cpp
Expand Down
12 changes: 12 additions & 0 deletions examples/tcpclient/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.15.0)
# directory name to be used as project name
project(tcpclient VERSION 1.0.1)
set(ADDCV NO)
# CMakeM1 checks ADDCV variable whether to include OpenCV
# and return LIBS variable with the list of libraries to link
# and also set WIN32OPT variable with WIN32 for Windows
include(${PROJECT_SOURCE_DIR}/../../CMakeM1.txt)
add_executable(${PROJECT_NAME} ${WIN32OPT}
${PROJECT_SOURCE_DIR}/src/${PROJECT_NAME}.cpp
)
target_link_libraries(${PROJECT_NAME} ${LIBS})
213 changes: 213 additions & 0 deletions examples/tcpclient/src/tcpclient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
// File: tcpclient.cpp
// Description: A simple wxWidgets TCP client sample
// Author: Yan Naing Aye
// Web: http://cool-emerald.blogspot.com
// MIT License (https://opensource.org/licenses/MIT)
// Copyright (c) 2018 Yan Naing Aye

// References
// [1] Guillermo Rodriguez Garcia, Vadim Zeitlin, "Server for wxSocket demo",
// https://github.com/wxWidgets/wxWidgets/blob/master/samples/sockets/server.cpp, 2009.
// [2] Julian Smart and Kevin Hock, "Cross-Platform GUI Programming with wxWidgets,"
// Pearson Education, Inc. 2006. ISBN: 0-13-147381-6.

#include "ce/ceUtil.h"
using namespace ce;
// IDs for the controls and the menu commands
enum
{
ID_BTNSEND = 101,
ID_TXTSEND,
ID_TXTRX,
SOCKET_ID,
CLIENT_OPEN = wxID_OPEN,
CLIENT_CLOSE = wxID_CLOSE,
// menu items
Minimal_Quit = wxID_EXIT,
Minimal_About = wxID_ABOUT
};

class MyFrame;
class MyApp : public wxApp
{
MyFrame *frame;
public:
ceTcpClient* _tcpclient;
void OnTcpSocketEvent(wxThreadEvent& event);
virtual bool OnInit();
};

// Define a new frame type: this is going to be our main frame
class MyFrame : public wxFrame
{
public:
// ctor(s)
MyFrame(MyApp* app, const wxString& title);
~MyFrame();
// event handlers (these functions should _not_ be virtual)
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void Print(std::string str);
void OnOpenConnection(wxCommandEvent& event);
void OnCloseConnection(wxCommandEvent& event);
void OnSend(wxCommandEvent& event);
void UpdateStatusBar();
private:
MyApp* _app;
wxButton* btnSend;
wxTextCtrl* txtSend;
wxTextCtrl *txtRx;
wxMenu* fileMenu;
wxMenu* helpMenu;
// any class wishing to process wxWidgets events must use this macro
wxDECLARE_EVENT_TABLE();
};

// event tables and other macros for wxWidgets
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(Minimal_Quit, MyFrame::OnQuit)
EVT_MENU(Minimal_About, MyFrame::OnAbout)
EVT_MENU(CLIENT_OPEN, MyFrame::OnOpenConnection)
EVT_MENU(CLIENT_CLOSE, MyFrame::OnCloseConnection)
wxEND_EVENT_TABLE()

IMPLEMENT_APP(MyApp)

// 'Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;

// depending on your system, some ports such as 3000, 8000, 8080 should be used with cautions
this->_tcpclient = new ceTcpClient(this,SOCKET_ID);
this->_tcpclient->SetRemote("localhost",7225);
Connect(SOCKET_ID, wxEVT_THREAD, wxThreadEventHandler(MyApp::OnTcpSocketEvent));
frame = new MyFrame(this,"TCP Client using ceUtil lib");
frame->Show(true);
this->frame->Print("Click Open Session menu to start a connection");
return true;
}

void MyApp::OnTcpSocketEvent(wxThreadEvent& event)
{
std::vector<char> v = event.GetPayload<std::vector<char>>();
std::string s = event.GetString().ToStdString();
int i = event.GetInt();
std::string str = "Socket event: Rx vec = "+ceMisc::cvec2hex(v)+", ip ="+s+", port = "+ std::to_string(i);
printf("%s\n",str.c_str());
this->frame->Print(str);
}

// frame constructor
MyFrame::MyFrame(MyApp* app, const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(390, 280),
wxDEFAULT_FRAME_STYLE ^ wxRESIZE_BORDER),_app(app)
{
#if wxUSE_MENUS
// create a menu bar
wxMenu *fileMenu = new wxMenu;

// the "About" item should be in the help menu
wxMenu *helpMenu = new wxMenu;
helpMenu->Append(Minimal_About, "&About\tF1", "Show about dialog");

fileMenu->Append(CLIENT_OPEN, "&Open session\tAlt-O", "Connect to server");
fileMenu->Append(CLIENT_CLOSE, "&Close session\tAlt-C", "Close connection");
fileMenu->Append(Minimal_Quit, "E&xit\tAlt-X", "Quit this program");

// now append the freshly created menu to the menu bar...
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append(fileMenu, "&File");
menuBar->Append(helpMenu, "&Help");

// ... and attach this menu bar to the frame
SetMenuBar(menuBar);
#endif // wxUSE_MENUS

#if wxUSE_STATUSBAR
// create a status bar just for fun (by default with 1 pane only)
CreateStatusBar(2);
SetStatusText("TCP client using ceUtil lib");
#endif // wxUSE_STATUSBAR
btnSend = new wxButton(this, ID_BTNSEND, wxT("Send"),
wxPoint(5, 5), wxSize(100, 25));
txtSend = new wxTextCtrl(this, ID_TXTSEND, wxT("Hello!"),
wxPoint(120, 5), wxSize(250, 25));
txtRx = new wxTextCtrl(this, ID_TXTRX, wxT(""),
wxPoint(5, 35), wxSize(365, 125), wxTE_MULTILINE);

Connect(ID_BTNSEND, wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(MyFrame::OnSend));
}

MyFrame::~MyFrame()
{
// No delayed deletion here, as the frame is dying anyway
}

// event handlers
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
// true is to force the frame to close
Close(true);
}

void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(wxString::Format
(
"ceUtil TCP client sample\n"
"\n"
"Author: Yan Naing Aye \n"
"Web: http://cool-emerald.blogspot.com"
),
"About ceUtil TCP client sample",
wxOK | wxICON_INFORMATION,
this);
}

void MyFrame::Print(std::string str)
{
txtRx->AppendText(wxString::Format(wxT("%s\n"),str));
}

void MyFrame::UpdateStatusBar()
{
//fileMenu->Enable(CLIENT_OPEN, !_app->_tcpclient->IsConnected());
//fileMenu->Enable(CLIENT_CLOSE, _app->_tcpclient->IsConnected());
//if (_app->_tcpclient->IsConnected()) {
// //SetStatusText(wxString::Format(wxT("%s:%u"),
// // addr.IPAddress(), addr.Service()), 1);
// SetStatusText(wxString::Format(wxT("Connected")), 1);
//}
//else {
// SetStatusText(wxString::Format(wxT("Not connected")), 1);
//}
}

void MyFrame::OnOpenConnection(wxCommandEvent& WXUNUSED(event))
{
_app->_tcpclient->Open();
// fileMenu->Enable(CLIENT_OPEN, false);
// fileMenu->Enable(CLIENT_CLOSE, false);
//update status
this->UpdateStatusBar();
}

void MyFrame::OnCloseConnection(wxCommandEvent& WXUNUSED(event))
{
_app->_tcpclient->Close();

//update status
this->UpdateStatusBar();
}

void MyFrame::OnSend(wxCommandEvent& WXUNUSED(event))
{
wxString str = txtSend->GetValue();
wxCharBuffer buffer = str.ToUTF8();
size_t txn = buffer.length();//for non-ASCII chars, having more than one byte per char
std::vector<char> vc{buffer.data(), buffer.data()+txn};
_app->_tcpclient->Tx(vc);
}
60 changes: 60 additions & 0 deletions examples/tcpclient/tcpclient.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash

SCRIPTNAME=`basename "$0"`
PRJNAME="${SCRIPTNAME%.*}"
SCRIPTDIR="${0%/$PRJNAME.*}"
echo "Project: $PRJNAME"
echo "Script directory: $SCRIPTDIR"

if [ $# == 1 ]; then
opt_sh=$1
else
echo "You can input argument:"
echo " 'cmake' : to generate cmake files, build, and install"
echo " 'build': to build and run"
echo " ..."
read -p "Input an option: " opt_sh
fi

if [[ "$opt_sh" == "" ]]; then
opt_sh="build"
fi

echo "Option: $opt_sh"
echo " ."
echo " ."
echo " ."

cd $SCRIPTDIR
if [[ "$opt_sh" == "cmake" ]]; then
echo "Preparing cmake file"
if [[ ! -d "./build" ]]; then
mkdir -p build
fi
rm -r ./build/*
cd build
cmake -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=/usr/local \
..
cd ..
echo " ."
echo " ."
echo " ."
fi

if [[ $opt_sh == "cmake" ]] || [[ $opt_sh == "build" ]]; then
echo "Building ..."
cd $SCRIPTDIR/build && make # && sudo make install
if [[ $? == 0 ]]; then
echo "Build successful"
echo "Running ..."
./$PRJNAME
else
echo "Error in compiling"
fi
else
echo "Running ..."
./$PRJNAME
fi


31 changes: 31 additions & 0 deletions examples/tcpclient/tcpclient/tcpclient.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcpclient", "tcpclient.vcxproj", "{9E6EFA9E-8164-4807-B820-F97C9CFBFED1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9E6EFA9E-8164-4807-B820-F97C9CFBFED1}.Debug|x64.ActiveCfg = Debug|x64
{9E6EFA9E-8164-4807-B820-F97C9CFBFED1}.Debug|x64.Build.0 = Debug|x64
{9E6EFA9E-8164-4807-B820-F97C9CFBFED1}.Debug|x86.ActiveCfg = Debug|Win32
{9E6EFA9E-8164-4807-B820-F97C9CFBFED1}.Debug|x86.Build.0 = Debug|Win32
{9E6EFA9E-8164-4807-B820-F97C9CFBFED1}.Release|x64.ActiveCfg = Release|x64
{9E6EFA9E-8164-4807-B820-F97C9CFBFED1}.Release|x64.Build.0 = Release|x64
{9E6EFA9E-8164-4807-B820-F97C9CFBFED1}.Release|x86.ActiveCfg = Release|Win32
{9E6EFA9E-8164-4807-B820-F97C9CFBFED1}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D0A51A18-2F03-4C7F-9C10-DB3BA0B948C1}
EndGlobalSection
EndGlobal
Loading

0 comments on commit 3bbe875

Please sign in to comment.