Selasa, 17 Desember 2013

SFML Network dengan Thread untuk client server [bagian 1]

SFML Network Server dengan Thread
ini adalah jurney saya tentang SFML, khusus untuk bagian sfml::net dan sf::thread. 


membuat program untuk multi user client server tidaklah mudah karena menyangkut akses konkurent dari para user. SFML memberikan fasilitas thread untuk memudahkan pemrograman aplikasi client server.
berikut ini contoh kodenya:


//=======main.cpp========
#include <iostream>
#include <time.h>
#include <sstream>
#include <string>
#include <cstdio>
#include <fstream>
#include <SFML\Network.hpp>
#include "config.h"
#include "client.h"
#include "server.h"                                   
#include "ui.h"
sf::Mutex logMutex;
Config config;
std::deque<std::wstring> output;
const sf::Uint16 MAX_SERVERNAME_DISPLAY_LENGTH = 25;
const sf::Uint32 MAX_LOG_LENGTH = 200;
const sf::Uint16 LOG_INDENT = 3;
const sf::Uint16 MAX_CLIENTNAME_LENGTH = 32;

int main(int argc, char * argv[]) {
//Retrieve IP-adress
    config.port = UINT16(8888);
    config.max_connections = 6;
    config.name = std::wstring(L"SPIRO");
    config.password = std::wstring(L"qwerty");

    //config.PublicIP =
    config.LocalIP = "192.168.1.2";
    config.PublicIP = "192.168.1.2";
    if(Server::init()) {
        sf::Thread uiThread(uiLoop);
        uiThread.launch();
        logMutex.lock();
        output.push_front(L"Server successfully started!");
        for(sf::Uint16 i=0; i<4; i++) {output.push_front(L"");}
        logMutex.unlock();
        // This blocks the 'main' thread untill the uiThread quits
        uiThread.wait();
    } else {
        writeToLog(L"Error, shutting down. Press any key to continue.");
    }
    Server::terminate();
    return 0;
}
//=======main.cpp========


penjelasan kode sumber:


selain dari: #include <SFML\Network.hpp>, #include "config.h", #include "client.h", #include "server.h", dan #include "ui.h"
adalah header standar dari c++, sudah disediakan oleh compiler. kelima #include tersebut digunakan untuk memberitahu kompiler agar membuka kelima file header tersebut sebelum kode dibawahnya dibaca oleh kompiler.


biasanya suatu program c++ akan dibentuk oleh banyak object-object yang terpisah dan di link kedalam satu file executable/dll. nah kebanyakan fungsi dari header file adalah memberikan symbol-symbol dari tiap tiap object kepada source code yang memanggilnya. sebagai contoh pemberian perintah #include <SFML\Network.hpp> akan memberitahukan kompiler bahwa modul object yang terdapat didalam file sfml-network.dll dapat dipanggil dengan menggunakan symbol-symbol yang terdapat didalam SFML\Network.hpp.
Selain module SFML yang memang sudah tersedia, mari kita bahas #include "config.h" berikut ini kode sumbernya:


//=======config.h==========
#include <fstream>
#include <windows.h>
#include <SFML\Network.hpp>
struct Config {
    // Run-time config
    sf::IpAddress LocalIP;sf::IpAddress PublicIP;std::fstream logFile;COORD bufferSize;
    //IPConfig
    sf::Uint16 port;sf::Uint16 max_connections;sf::Uint32 timeout;
    //Server
    std::wstring name;std::wstring password;
    //UI
    sf::Uint16 verbose_level;
    bool logToFile;
    Config() : port(0), max_connections(0), timeout(), name(), password(), LocalIP(sf::IpAddress::None), PublicIP(sf::IpAddress::None), verbose_level(0), logToFile(false), logFile(), bufferSize() {}
};
extern Config config;
extern const sf::Uint16 MAX_SERVERNAME_DISPLAY_LENGTH;
extern const sf::Uint32 MAX_LOG_LENGTH;
extern const sf::Uint16 LOG_INDENT;
extern const sf::Uint16 MAX_CLIENTNAME_LENGTH;
//======config.h========


source code config.h berisikan perintah struct Config{...}  perintah ini menyatakan agar kompiler membuat struktur data di memory dengan inisial Config. Perintah standar c++ untuk struct{} adalah:


struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
} object_names;


kemudian perhatikan baris : extern Config config;
perintah extern akan membuat structure data "Config" dapat dipanggil sebagai symbol "config" oleh object lain diluar dirinya sendiri. inilah kemudian menjadi #include pada kode sumber lainnya.


struktur Config terdiri dari member-member yang kelak dapat dipanggil dengan pernyataan seperti config.LocalIP, config.port dan sebagainya sesuai dengan member name yang ada didalam struktur tersebut. sebagai contoh: sf::IpAddress LocalIP member didalam structur Config. baris tersebut menyiratkan bahwa jika "LocalIP" dipanggil, maka "sf::IpAddress" akan melakukan tugasnya dan jika ada nilai kembalian dari "sf::IpAddress" maka nilai tersebut adalah nilai bagi  "LocalIP".


catatan: "sf::IpAddress" adalah fungsi yang ada didalam modul SFML yang akan meretrieve nilai alamat IP yang aktif didalam operating system.


sampai disini maka program main.cpp kita akan dapat mengenali suatu object data buatan dengan nama Config. lihat pada main.cpp disana terdapat definisi atas Config sebagai config dan selanjutnya digunakan didalam int main{} dengan syntax:

config.LocalIP = xxxxxxx
config.port = UINT16(8888);
config.max_connections = 6;
config.name = std::wstring(L"SPIRO");
config.password = std::wstring(L"qwerty");



Tidak ada komentar:

Posting Komentar