Xedi.Xermawan's Blog

personal-technical blog

New Design Calendar App

leave a comment »

Selamat tahun baru 2017 !

new

 

Untitled-1

Written by XediXermawan

March 7, 2017 at 7:57 am

Mengganti CPU Fan

leave a comment »

Motivasi saya mengganti cpu fan bukan karena cpu nya kepanasan –seperti alasan yg lain–, namun karena cpu fan saya super berisik, dan sudah nggak bisa ditolerir oleh human being . saya nggak peduli pada CPU panas pada dasarnya, selama cpu nggak mati berarti Oke :d .Awalnya saya pakai cpu fan bawaan processor, fannya berlabel AMD, ( tapi anehnya dibawah kipas berlabel Cooler Master ) . Sekarang saya ganti dengan Deepcool GAMMAX 400. Sempat bingung nyari merk fan yang cocok dengan motherboard & processor saya, AM3+ socket, dan juga pertimbangan harga. Antara cooler master, noctua, zalman, etc, etc. ( ternyata banyak juga merk cpu fan :d ) . Sebelum mengganti cpu fan, sudah nyoba beberapa cara ( an idiot way ) untuk meredam noisenya, –termasuk memasukkan cpu kedalam lemari–, namun semua ngggak berhasil,  suara tetap tembus . Deepcool GAMMAX 400 , cukup silent, bahkan sekarang yang lebih kedengaran kipas casing .  some pics :

-kiri : deepcool gammax 400 , kanan: kipas lama

WP_20150214_025 -on hand :

WP_20150214_026

-ketika komputer nyala : ada led biru, menurut saya led ini terlalu besar dan kebanyakan ( buang-buang energi saja ). 1 led kecil cukup.

WP_20150214_035

–temperatur cpu  (setelah beberapa saat main game 3d)

cpu_temp_new_fan

edie // 14022015 //  Jakarta

Written by XediXermawan

February 14, 2015 at 5:12 pm

Posted in computer related

Mencoba Cmake ( a Cmake intro )

leave a comment »

Visual Studio adalah favorite ide pemrograman saya. Sudah sejak lama saya pakai, kira-kira sejak 4 tahun yang lalu. Mungkin menjadi favorite karena kebiasaan 🙂 dan juga visual studio mudah dipakai. Walaupun kadang ada juga bugs ‘aneh’ yang terjadi selama nge-build project dengan VS. Sayangnya, ‘build file’ dari VS tidak bisa dipakai di environment lain, misalnya mau build pakai gcc di Linux. Oleh karena itulah harus ada cara lain yang harus dipakai. Berikut sebagai contoh case saya :

Misalnya saya memiliki super advanced top secret project dengan informasi sebagai berikut :

[1] struktur file-file project :

              ->project_root_dir

              ->HelloSource.cpp file

              ->PrintLib dir

                      ->PrintHello.h file

             ->PrintHello.cpp file

[2] project diatas akan di-build dengan output sebagai berikut :

           -HelloSource.cpp —> executable file , yang menggunakan PrintLib (static linked)

           -PrintLib —> static library

          -Penggunaan PrintLib bisa di ON-OFF melalui macro ( o yeah, macro define, I like it )

[3] source code : HelloSource.cpp

          /* hello apps project */

          #include <iostream>

          #include “HelloVersion.h”

          #ifdef USE_PRINTLIB

          #include “PrintHello.h”

          #endif

          using namespace std;

          int main(char* argc, char** argv)

          {

                   cout << “hello ” << endl;

                   cout <<” hello version : “<< Hello_VERSION_MAJOR <<“-“<<Hello_VERSION_MINOR<<endl;

                   #ifdef USE_PRINTLIB

                   PrintHelloFunc();

                   #endif

                   return 0;

          }

[4] source code : PrintHello.h

          #include <iostream>

          void PrintHelloFunc();

[5] source code : PrintHello.cpp

          #include “PrintHello.h”

          void PrintHelloFunc()

          {

                   std::cout << ” hey hello i’m here. printed from hellolib ” << std::endl;

          }

Pertanyaannya, Bagaimana agar project diatas bisa build-able beberapa platform dengan beda compiler ?

Banyak cara, dari cara manual ( buat build script untuk masing-masing platform ) atau dengan tools misalnya : autotools, scons, jam, waf, cmake.yang terakhir: cmake, saya sering mem-build project dari internet yang menggunakan cmake, jadi lebih kenal dengan yang satu ini. Kenyataannya cmake sudah secara luas digunakan di opensource project sejak lama. Build sistem yang lain yang pernah saya coba, dan sangat mudah (dari segi user yang akan mem-build project tersebut) adalah build sistem dari boost library : boost-jam . sangat mudah nge-buildnya.

Kali ini saya tertarik mempelajari bagaimana membuat cmake file. cmake file itu semacam “template” make file atau meta make file. cmake file adalah file text yang berisi deskripsi project dengan syntax cmake dan disimpan dengan nama CMakeLists.txt. Kalau cmake file suatu project sudah dibuat, file ini bisa digunakan untuk meng-generate real make file yang bisa dipakai compiler. tergantung compiler apa yang dipakai . beberapa yang didukung :

          -Visual C++ ( sln & vcxproj ),

          -Kdevelop3, Eclipse, XCode,

          -makefiles (Unix,NMake, Borland, Watcom, MinGW, MSYS,Cygwin)

          -Code::Blocks

Dari daftar diatas, yang pernah saya coba adalah generate VS (solution & project) dan makefile untuk linux.

Dari deskripsi project diatas saya bisa membuat cmake file dengan struktur :

          ->project_root_dir

          ->CMakeLists.txt file                   cmake ke-1 (main)

          ->PrintLib dir

                   ->CMakeLists.txt file          cmake ke-2

          ->HelloVersion.h.in file untuk setting Define

 source file CMakeLists.txt ke-2 : ( hanya 1 baris )

          add_library(PrintLib PrintHello.cpp)

source file CMakeLists.txt ke-1 :

          #this is a cmake comment

          cmake_minimum_required (VERSION 2.6)

          #project name

          project (Hello)

          #version

          set (Hello_VERSION_MAJOR 1)

          set (Hello_VERSION_MINOR 0)

          #option can be turned on/off when generate real make file

          option ( USE_PRINTLIB “use print library” ON )

          configure_file (

                   “${PROJECT_SOURCE_DIR}/HelloVersion.h.in”

                   “${PROJECT_BINARY_DIR}/HelloVersion.h”

          )

          include_directories (“${PROJECT_BINARY_DIR}”)

          if (USE_PRINTLIB)

                   include_directories (“${PROJECT_SOURCE_DIR}/PrintLib”)

                   add_subdirectory(PrintLib)

                   set (EXTRA_LIBS ${EXTRA_LIBS} PrintLib)

          endif (USE_PRINTLIB)

          #tell cmake that Hello is executable

          add_executable(Hello HelloSource.cpp)

          #tell cmake that Hello linked with extralibs ( printlib )

          target_link_libraries(Hello ${EXTRA_LIBS})

          install(TARGETS Hello DESTINATION bin)

source file HelloVersion.h.in :

          // version for Hello project

          #define Hello_VERSION_MAJOR @Hello_VERSION_MAJOR@

          #define Hello_VERSION_MINOR @Hello_VERSION_MINOR@

          #cmakedefine USE_PRINTLIB

file tambahan adalah HelloVersion.h.in untuk mengatur version dan macro define. Kalau dibaca deskripsi output project saya diatas dan apa yang ada di cmakelist.txt semuanya tampak self explanatory. Dari CMakeLists.txt ini kita bisa meng-generate solution & project di windows & makefile di linux ( sebagai 2 test case untuk mencoba ) . di Ms-Windows bisa memakai cmake GUI.

cmake_flow

cmake_flow

Cmake file yang dipakai diatas adalah yang paling sederhana. Terdapat beberapa perintah yang lain, misalnya find_package, find_library, export, dan lainnya .

edie // 13022015 // Jakarta

Written by XediXermawan

February 13, 2015 at 4:30 pm

Website sebagai standalone desktop apps

with 3 comments

suatu saat punya pertanyaan, kalau misalnya saya bisa web programming, bisa ndak web yang saya buat dijalankan di desktop sebagai stand alone native application ?
jawaban : bisa . dengan https://github.com/nwjs/nw.js , sebuah halaman web bisa dijadikan standalone app di desktop.
nw.js pada dasarnya adalah “internet browser” , jadi nantinya bisa multipaltform ( windows, linux, macOS )
contohnya : https://github.com/LightTable/LightTable ( sebuah code editor apps )

Written by XediXermawan

February 12, 2015 at 4:23 am

Posted in computer related

Galeri kalender 2015 2016 ( Indonesia )

with one comment

Jakarta, November 16, 2014

Beberapa galeri kalender 2015 Indonesia ( dengan pasaran jawa : pon , pahing , kliwon , legi , wage )
download :  LINK

Kalender 2015 Indonesia

Kalender 2015 Indonesia

kalender 2015 Indonesia yang lain :  LINK

dibuat dengan program

Update Oktober 2015 :

saya membuat banyak sekali kalender 2016 dengan berbagai macam type font. bisa didownload disini :
kalender_2016_VastShadow-Regular.ttf

Update Desember 2015 :

Beberapa minggu lalu saya membuat kalender Indonesia versi Android. di dalam versi android dimasukkan juga liburan dan cuti bersama 2016. Kalau tertarik bisa diinstall disini.

atau scan barcode dibawah ini :
Kalender_Indonesia_Link

Tampilan Kalender Indonesia versi Android :

Kalender_Indonesia_2016

Update Maret 2016 :

penambahan fitur kalender lunar / kalender bulan ( dipakai di kalender Jawa dan Kalender Hijriah ). Namun untuk kalender hijriah akurasi nya +/- 1 hari.

Update Desember 2016 :
Kalender Indonesia 2017 telah diupdate dengan libur nasional dan cuti bersama 2017, termasuk penambahan 3 hari libur dari SKB 3 menteri 6 desember 2016 : 1 Juni, 2 Januari sebagai cuti bersama, dan penambahan 1 hari & pergeseran libur di cuti bersama idul fitri 1438 H ( juni 2017 ).

Download Kalender Indonesia di Android disini .

atau scan barcode dibawah ini :
Kalender_Indonesia_Link

Semoga bermanfaat 🙂

Mengganti power supply

with 2 comments

Beberapa malam hari yang lalu, saat lagi menggunakan komputer, secara tidak sengaja, kaki saya menyentuh kabel power dari power supply, dan tiba tiba komputer saya mati, dibarengi dengan percikan api. Cukup membuat kaget. Kecelakaan kecil yang mengkawatirkan . Saya coba lagi nyalakan 2-3 kali, tidak ada reaksi. Benar benar mati. Tidak ada yang saya lakukan setelah itu, karena saya langsung tidur. Saat akhir pekan, saya coba tes lagi kondisi PC, siapa tau ada keajaiban, haha. Ya, tentu saja, masih sama, tidak mau menyala. Mulai kawatir, semoga bukan motherboard/cpu yang rusak. Dugaan pertama saya adalah : power supply. Rencananya, PC nya akan saya bawa ke toko komputer di mall dekat sini ( perkiraan 2-3 km ), namun karena CPU nya lumayan berat , saya batalkan. Sebenarnya yang bikin berat casing nya. Ok, saya mencoba lepas power supplynya . Saya cari obeng, hmm untungnya nemu obeng di dalam tasku. (selain itu saya tidak punya peralatan, karena saya baru datang di kota baru ini ). Saya tidak ingat secara pasti , kenapa ada obeng ditasku 😁 . Saya sudah lama tidak buka buka casing komputer, terakhir kali saat saya masih pakai pentium 3 700 mhz ( tahun 2009 ). Namun ternyata tidak jauh berbeda dengan komputer pc model baru. Sedikit masalah yang saya hadapi : kabel supply nya disusun lumayan rapi oleh pak perakit dulu, ini artinya apa ?, : kabelnya lumayan susah untuk dilepas ! , butuh waktu 1,5 jam untuk melepasnya. Setelah lepas, saya tes power supply nya, apakah benar benar rusak atau tidak. Cukup koneksikan kabel hijau dan hitam, dan lihat kipasnya berputar atau tidak. Sedikit berita gembira :power supplynya yang rusak. Saya tidak mengecek lebih dalam bagian mana yang rusak , kalau yang rusak sekering, mungkin masih bisa diganti. Keesokan harinya, saya mencari power supply pengganti di toko komputer. Cukup hati hati memilih watt ( juga pure wattnya ) dan merk power supply, karena dia yang akan mengaliri daya ke komponen penting lain, yang harganya lebih mahal : mobo, cpu, video card , memory . Akhirnya dapat juga power supply yang cocok .( setelah keliling putar putar mencari jalan menuju & keluar dari mall gede ga jelas *sigh* ) . Setelah sampai di kos, saya langsung pasang ke komputer. Saya kira memasang akan lebih susah, ternyata tidak, dan yuhuuu, komputerku yang super berisik menyala kembali. Haha. Semoga power supply nya oke oke aja . Beberapa screenshoot. tengah : power supply yang baru .

Written by XediXermawan

October 5, 2014 at 3:18 pm

Posted in computer related

Tagged with

Rendering animated GIF file

with 3 comments

gif file ( http://en.wikipedia.org/wiki/Graphics_Interchange_Format ) is very popular format , you can share funny animation, emotion, a splash for ads, etc. All web browser support this format. do you interested in how game or application (non-web) render animated gif ? . here my experiment result :

( set video quality to 480p  )

info :
rendering : DirectX 11
language : c/c++
GIF decoder : libnsgif

Written by XediXermawan

May 30, 2014 at 12:31 am

Posted in C/C++ Diary

Tagged with , , ,

TCP Client Server dengan Winsock2

leave a comment »

Untuk keperluan selanjutnya di pengembangan game yang sedang saya buat ( 😮 ), saya memerlukan program yang bisa di tweak lewat program lain. Dengan kata lain 2 program yang saling bisa berkomunikasi. Cara yang bisa dicapai , pakai file sharing atau dengan cara yang pas : pakai networking tcp / udp . Kalau mau buat program dengan kemampuan networking, cara yang bijaksana mungkin pakai 3rd party library yang sudah cukup populer dan reliable. Di antaranya, yang saya ketahui dan sepertinya sudah terbukti bagus : boost-asio ( free ), raknet ( free untuk hobyist ), libevent ( free ), etc. ada yang lain ?. Tapi saya pinginnya ndak usah pakai 3rd party lib, lagipula program yang akan saya buat cukup sederhana. winsock2 & c/c++ . itu pilihannya. dan rasanya akan fun juga buat program nya hehe. Sebagai pemanasan awal dengan winsock2 ( saya pemula ) , saya perlu membuat program seperti ini : ada client dan server. client bisa kirim data ke server. server bisa kirim data ke client. jika client nya lebih dari satu, client bisa kirim data ke client yang lain. representasi dari program ini adalah program “chatting” :d .
kemampuan server dalam keadaan running :
– stand by & listening kalau ada client mau membuat koneksi.
– setiap ada client tersambung, server akan membuat handler yang menangani koneksi ke client tersebut berdasarkan socket id. ( dalam test program dipost ini, setiap ada client, server membuat thread baru, untuk menanganinya ).
– server bisa kirim data ke client lewat console
– ada > 3 thread . 1 main thread: untuk menangkap command line dari user, 1 thread untuk “stand by” / connection acceptor, dan n thread , untuk n client yang tersambung. ya sebenarnya ndak benar ( bisa di optimize pakai thread pool mungkin nantinya ).

kemampuan client dalam keadaan running :
– connect ke server
– kirim data ke server
– ada 2 thread, 1 main thread, 1 client handler thread ( data receiver & sender )
– port hardcoded : 22536

catatan :
[1] saya membuat socket mode ke non-blocking , artinya pemanggilan fungsi2 winsock seperti connect, recv, send tidak akan mem-blok jalannya program loop. jadi non-blocking & di thread lain selain main thread.
u_long iMode = 1;  // iMode=0, blocking mode, default value
ioctlsocket(ConnectSocket, FIONBIO, &iMode);
[2] untuk sharing data antar thread, saya menggunakan concurrent queue dari blog Anthony William http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html yang saya modifikasi menggunakan std library ( awalnya pakai boost )
[3] data yang dikirim berupa string.

Beberapa pertanyaan :
– apa cara di catatan no [1] ( non-blocking & di thread lain ) efektif ?
– saat memakai non-blocking mode, kalau mengirim data byte yang sangat besaarr , apakah semuanya terkirim langsung ATAU setelah beberapa call sent?

Reference :
MSDN winsock2 ( belum semuanya saya baca 😐 )

berikut code program chat client & server yang saya buat :

(server code) : ~288 baris

// xedi xermawan < edi.ermawan@gmail.com >
// May 27, 2014
// tcp client server networking test using winsock2
// server code

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <queue>

#include "concurrent_queue.hpp"

#pragma comment (lib, "ws2_32.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "22536"

struct XDclient_info
{
int socket_id;
struct sockaddr_in address;
};

class XDclient
{
public:
XDclient(XDclient_info& clientinfo)
{
m_clientinfo = clientinfo;
m_recvbuflen = DEFAULT_BUFLEN;
m_islive = true;
m_thread = new std::thread(&XDclient::run, this);
}
bool isLive()
{
return m_islive;
}
XDclient_info getinfo() const
{
return m_clientinfo;
}
~XDclient()
{
m_thread->join();
delete m_thread;
}
std::string get_data()
{
std::string ret_str = "";
if (!m_queue.empty())
{
m_queue.try_pop(ret_str);
}
return ret_str;
}
private:
XDclient_info m_clientinfo;
std::thread* m_thread;
char m_recvbuf[DEFAULT_BUFLEN];
int m_recvbuflen;
bool m_islive;
concurrent_queue <std::string> m_queue;

void run()
{
while (m_islive)
{
unsigned int result_recv = recv( m_clientinfo.socket_id, m_recvbuf, m_recvbuflen, 0);
int nError = WSAGetLastError();
if (nError != WSAEWOULDBLOCK&&nError != 0)
{
printf("Client Error: %d\n", nError);
printf("Client disconnected: %d\n", nError);
m_islive = false;
}
else if (result_recv != INVALID_SOCKET && result_recv!= 0)
{
m_recvbuf[result_recv] = '\0';
std::string str_send(m_recvbuf);
m_queue.push(str_send);
}
else if (result_recv == 0)
{
printf("Client disconnected: %d\n", nError);
m_islive = false;
}
// give a sleep, avoid high percentage cpu usage
Sleep(50);
}
}
};

class XDserver
{
public:
XDserver()
{
m_recvbuflen = DEFAULT_BUFLEN;
m_isrun = true;
m_thread = new std::thread(&XDserver::run, this);
}
~XDserver()
{
m_isrun = false;
m_thread->join();
delete m_thread;
}
void run()
{
WSADATA wsaData;
int result_ ;

SOCKET listen_socket = INVALID_SOCKET;
SOCKET client_socket = INVALID_SOCKET;

struct addrinfo *result = NULL;
struct addrinfo hints;

char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;

// init
result_ = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result_ != 0) {
printf("WSAStartup failed with error: %d\n", result_);
}

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

// get info address for host
result_ = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (result_ != 0) {
printf("getaddrinfo failed with error: %d\n", result_);
WSACleanup();
}
// create socket
listen_socket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (listen_socket == INVALID_SOCKET) {
printf("socket failed. error code : %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
}
// set-up socket listening
result_ = bind(listen_socket, result->ai_addr, (int)result->ai_addrlen);
if (result_ == SOCKET_ERROR) {
printf("bind failed. error code: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(listen_socket);
WSACleanup();
m_isrun = false;
}
if (!m_isrun)
return;
freeaddrinfo(result);

result_ = listen(listen_socket, SOMAXCONN);
if (result_ == SOCKET_ERROR) {
printf("listen failed. error code: %d\n", WSAGetLastError());
closesocket(listen_socket);
WSACleanup();
}
// set to non-blocking mode
u_long iMode = 1;
ioctlsocket(listen_socket, FIONBIO, &iMode);
int t_clientAddressLen = sizeof(struct sockaddr_in);
struct sockaddr_in t_clientAddress;
// server loop
while (m_isrun)
{
// check new client connected
client_socket = accept(listen_socket, (struct sockaddr *)&t_clientAddress, &t_clientAddressLen);
int nError = WSAGetLastError();
if (nError != WSAEWOULDBLOCK&&nError != 0)
{
// todo :
}
else if (client_socket != INVALID_SOCKET)
{
XDclient_info clientinfo;
clientinfo.address = t_clientAddress;
clientinfo.socket_id = client_socket;

XDclient* clientnew = new XDclient(clientinfo);
m_clients.push_back(clientnew);
if (client_socket == INVALID_SOCKET) {
printf("accept failed. error code: %d\n", WSAGetLastError());
}
}
// check client live
for (std::vector< XDclient* >::iterator it = m_clients.begin(); it != m_clients.end(); it++)
{
if (!(*it)->isLive())
{
delete *it;
m_clients.erase(it);
break;
}
}
// check if there are data need to be sent
if (!m_queue.empty())
{
std::string str = "";
m_queue.try_pop(str );
std::cout << " send data: " << str.c_str() <<std::endl;
for (std::vector< XDclient* >::iterator it = m_clients.begin(); it != m_clients.end(); it++)
{
int m_recvbuflen;
int sendresult = send((*it)->getinfo().socket_id, str.c_str(), str.length(), 0);
if (sendresult == SOCKET_ERROR)
{
std::cout << " send failed. error code " << sendresult << std::endl;
}
}
}
for (std::vector< XDclient* >::iterator it = m_clients.begin(); it != m_clients.end(); it++)
{
std::string str_data = (*it)->get_data();
if (str_data != "")
{
for (std::vector< XDclient* >::iterator it2 = m_clients.begin(); it2 != m_clients.end(); it2++)
{
if (*it != *it2)
{
int sendresult = send((*it2)->getinfo().socket_id, str_data.c_str(), str_data.length(), 0);
if (sendresult == SOCKET_ERROR)
{
std::cout << " send failed. error code " << sendresult << std::endl;
}
}
}
}
}
// give a sleep, avoid high percentage cpu usage
Sleep(50);
}
}
void senddata(std::string& str)
{
m_queue.push(str);
}
bool isLive()
{
return m_isrun;
}
private:
char m_recvbuf[DEFAULT_BUFLEN];
int m_recvbuflen;
bool m_isrun;
std::thread* m_thread;
std::vector< XDclient* > m_clients;
concurrent_queue <std::string> m_queue;
};

class Games
{
};

int __cdecl main(int argc, char** argv)
{
XDserver* server = new XDserver();
std::cout << "welcome to the server"<<std::endl;
std::cout << "type an input to broadcast to all client. ""exit"" to close program " << std::endl;
while (server->isLive())
{
char str_in[512]="";
std::cin >> str_in;
std::string str_input(str_in);
server->senddata("server|"+str_input);
if (!str_input.compare("exit"))
{
break;
}
}
delete server;
std::cout << "server shutdown" << std::endl;
system("pause");
return 0;
}

(client  code) :  ~181 baris

// xedi xermawan < edi.ermawan@gmail.com >
// May 27, 2014
// tcp client server networking test using winsock2
// client code

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <queue>
#include <sstream>

#include "concurrent_queue.hpp"

// link to winsock2 static lib
#pragma comment (lib, "ws2_32.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "22536"

class XDclientapp
{
public:
XDclientapp(std::string& clientname, std::string& serveraddresss)
{
m_server_address = serveraddresss;
m_client_name    = clientname;
m_recvbuflen = DEFAULT_BUFLEN;
m_isrun = true;
m_thread = new std::thread(&XDclientapp::run, this);
}
~XDclientapp()
{
m_isrun = false;
m_thread->join();
delete m_thread;
}
void run()
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;

// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
}

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

// Resolve the server address and port
iResult = getaddrinfo( m_server_address.c_str(), DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
}

// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
}

// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
// set to non-blocking mode
u_long iMode = 1;
ioctlsocket(ConnectSocket, FIONBIO, &iMode);
freeaddrinfo(result);
int errorid;
while (1)
{
unsigned int result_recv = recv(ConnectSocket, recvbuf, recvbuflen, 0);

errorid = WSAGetLastError();
if (errorid != WSAEWOULDBLOCK && errorid != 0)
{
printf("Client disconnected: %d\n", errorid);
break;
}
else if (result_recv != INVALID_SOCKET && result_recv != 0)
{
// printf("Bytes received: %d\n", result_recv);
recvbuf[result_recv] = '\0';
printf("\n%s\n", recvbuf);
std::cout << m_client_name.c_str() << "(You) : ";
}
else if (result_recv == 0)
{
printf("Client disconnected: %d\n", errorid);
break;
}

// check if there are data need to be sent
if (!m_queue.empty())
{
std::string str = "";
m_queue.try_pop(str);
int m_recvbuflen;
int sendresult = send( ConnectSocket , str.c_str(), str.length(), 0);
if (sendresult == SOCKET_ERROR)
{
std::cout << " send failed. error code " << sendresult << std::endl;
}
}
// give a sleep, avoid high percentage cpu usage
Sleep(50);
}
}
void senddata(std::string& str)
{
std::string pstr = m_client_name + " : " + str;
m_queue.push(pstr);
}
private:
char m_recvbuf[DEFAULT_BUFLEN];
int m_recvbuflen;
bool m_isrun;
std::thread* m_thread;
concurrent_queue <std::string> m_queue;
std::string m_client_name;
std::string m_server_address;
};
//--
int __cdecl main(int argc,char** argv)
{
std::string clientname = "";
std::string serveraddress = "localhost";
std::cout << "Please enter your name: ";
std::getline(std::cin, clientname);

if (argc > 1)
{
serveraddress = argv[1];
}
XDclientapp* client = new XDclientapp(clientname, serveraddress);
std::cout << "welcome to the chat client" << std::endl;
std::cout << "type an input to broadcast to all client. ""exit"" to close program " << std::endl;
std::cout << "---" << std::endl;
while (1)
{
std::string str_input = "";
std::cout << clientname.c_str() << "(You) : ";
std::getline(std::cin, str_input);

client->senddata(str_input);
if (!str_input.compare("exit"))
{
break;
}
}
delete client;
return 0;
}

Screenshoot :
chatprogram
Download : source + vs project + binary ( hanya 39 kb ! ) .

Written by XediXermawan

May 27, 2014 at 6:43 pm

Posted in C/C++ Diary

Tagged with , , ,

#define problem

leave a comment »

Masalah kecil tapi fatal di projects C/C++ yang  saya temui ( dan parahnya terulang-ulang ), adalah penggunaan define. #define secara salah digunakan karena dicampur aduk antara definisi & pengecekannya. sebagai contoh ada 2 define :

#define USE_FEATURE_A
#define USE_FEATURE_B (1)

Dalam penggunaanya ada beberapa kemungkinan :

#ifdef USE_FEATURE_A
// code_inside_a.1
#endif
–>penggunaan yang benar. code “code_inside_a.1” akan ter-compile jika USE_FEATURE_A ter-define. kalau ingin menghilangkan code “code_inside_a.1”, USE_FEATURE_A harus un-define dengan komen : // #define USE_FEATURE_A

#if USE_FEATURE_A
// code_inside_a.2
#endif
–> salah. dan langsung kelihatan ( compile error ) jadi tidak perlu kawatir.

#if defined(USE_FEATURE_A)
// code_inside_a.3
#endif
–> benar. code “code_inside_a.3” akan ter-compile jika USE_FEATURE_A ter-define. kalau ingin menghilangkan code “code_inside_a.3”, USE_FEATURE_A harus un-define dengan komen : // #define USE_FEATURE_A

#if USE_FEATURE_B
// code_inside_b.1
#endif
–> benar. code “code_inside_b.1” ter-compile jika #define USE_FEATURE_B (1)

#if USE_FEATURE_B == 0
// code_inside_b.2
#endif
–>benar. code “code_inside_b.2” ter-compile jika #define USE_FEATURE_B (0)

#if defined(USE_FEATURE_B)
// code_inside_b.3
#endif
->salah. walaupun “code_inside_b.3” akan ter-compile ketika #define USE_FEATURE_B (1), namun “code_inside_b.3” juga akan ter-compile jika #define USE_FEATURE_B (0)

#ifdef USE_FEATURE_B
// code_inside_b.4
#endif
–>salah. walaupun “code_inside_b.4” akan ter-compile ketika #define USE_FEATURE_B (1), namun “code_inside_b.4” juga akan ter-compile jika #define USE_FEATURE_B (0)

best practice paling baik menurut saya memakai #define USE_FEATURE_B (1) dan secara konsisten menggunakan #if untuk mengecek.

 

Written by XediXermawan

May 21, 2014 at 5:22 pm

Posted in C/C++ Diary

Tagged with ,

Recent spare time projects

leave a comment »

I have been working on these projects in my spare time quite while ( like I work on it when I want work on it  :p )., but recently I’m disappointed with my progress ( apparently I’m busy and have difficulty when creating graphics assets by myself ). so I decided to upload source code to google code in case I’m interested again next time .There are 2 projects :

[1] unknown project 1. very simple game, almost done. keyword : C/C++,DirectX, Desktop App,Windows Phone 8

home project : https://code.google.com/p/my-fifteen-puzzle-dx/

svn link : https://my-fifteen-puzzle-dx.googlecode.com/svn/trunk

[2] unknown project 2 . also very simple game ( I like simple thing ). puzzle. gameplay complete. keyword : C/C++,DirectX, Desktop App, Windows Phone 8.

home project : https://code.google.com/p/proximity-game-clone2-dx/

svn link : https://proximity-game-clone2-dx.googlecode.com/svn/trunk

both of them actually same app I had made before . I rewrite again these projects using entirely new c/c++ code and using DirectX as graphics API. I also implemented some design pattern there. In case you are interested , check it out 🙂

game screenhoot running on windows phone 8 device
fiveteen_wp8

Written by XediXermawan

May 13, 2014 at 11:55 am