7 Mart 2018 Çarşamba

asio tcp socket Sınıfı

Giriş
Şu satırı dahil ederiz.
#include<boost/asio.hpp>
Kalıtım şöyledir.
socket -> basic_stream_socket -> socket_base
Bu sınıf oldukça tüy siklet (lightweight). İçinde sadece iki tane pointer var.

Constructor
İmzası şöyle.
basic_stream_socket(boost::asio::io_service & io_service);
Sınıf şöyle kurulur.
asio::ip::tcp::socket sock(ios);
Bu metod socket'i açmaz. bind() metodundan önce open() metodunu çağırmak gerekir.

Constructor - io_service + endpoint
Şöyle yaparız.
constexpr const char* port="2003";
asio::io_service ios;
tcp::resolver resolver(ios);
tcp::resolver::query query("localhost", port);
tcp::endpoint ep = *resolver.resolve(query);
tcp::socket sock (ios,ep);
Move Constructor ve Move Assignment
C++11'den itibaren bu sınıf move constructor'ı da destekliyor. Dolayısıyla shared_ptr ile birlikte kullanmaya gerek kalmadı.

Destructor
Açıklaması şöyle.
When a socket is destroyed, it will be closed as-if by socket.close(ec) during the destruction of the socket.
assign metodu
Şöyle yaparız.
SOCKET s = ...;
tcp::socket s(io_svc);
s.assign(tcp::v4(),s); 
async_connect metodu
Şöyle yaparız.
socket.async_connect(endpoint,handler);
Handler'ın imzası şöyledir.
void handler(const boost::system::error_code& error);
handler şöyledir.
handle_connect(const boost::system::error_code& error)
{...}
Eğer hata olursa handler'da şöyle yaparız.
void handle_connect(const boost::system::error_code& error)
{
  if (!error)
  {
    ...

  }
  else
  {
    std::cout << "Connect failed: " << error << "\n";
  }
}
Çıktı olarak şunu alabiliriz.
Connect failed: system:111
111 (ECONNREFUSED) anlamına gelir. Açıklaması şöyle
"The target address was not listening for connections or refused the connection request."
Aslında hata mesajını direkt yazdırmak daha iyi. Şöyle yaparız.
std::cout << "Connect failed: " << error.message() << "\n";
Örnek
Tüm iterator'lere otomatik bağlansı istersek şöyle yaparız.
boost::asio::ip::tcp::resolver resolver = ...;
boost::asio::ip::tcp::resolver::query query("127.0.0.1","80");
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
Daha sonra şöyle yaparız.
boost::asio::ip::tcp::endpoint endpoint = *iterator;
socket.async_connect(endpoint,
  boost::bind(&client::handle_connect, this,
    boost::asio::placeholders::error, ++iterator));
Handler içinde şöyle yaparız.
void handle_connect(const boost::system::error_code& error,
      boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
{

  if (!error)
  {
    ...
  }
  else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator())
  {
    std::cout << "handle_connect retry!\n";
    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
    socket.async_connect(endpoint,
      boost::bind(&client::handle_connect, this,
        boost::asio::placeholders::error, ++endpoint_iterator));
  }
  else
  {
    std::cout << "Connect failed: " << error.message() << "\n";
  }
}
async_read_some
Bu metod async_receive ile aynıdır. Açıklaması şöyle
The read operation may not read all of the requested number of bytes.
Açıklaması şöyle
"The read operation may not read all of the requested number of bytes. Consider using the async_read function if you need to ensure that the requested amount of data is read before the asynchronous operation completes."
null_buffers
Şöyle yaparız.
socket.async_read_some (boost::asio::null_buffers(),handler);
mutable buffer
Şöyle yaparız.
boost::asio::streambuf::mutable_buffers_type buf = streambuf.prepare(1024);

socket.async_read_some(buf,handler);
async_receive
Bu metod async_read_some ile aynıdır. Şöyle yaparız.

boost array
Önce bir buffer tanımlarız.
boost::array<char, 4096> m_ReceiveBuffer;
Daha sonra okuruz.
socket.async_read_some (boost::asio::buffer (m_ReceiveBuffer), handler);
char []
Önce bir buffer tanımlarız.
static const size_t m_BufLen = 100;
char m_RecieveBuffer[m_BufLen];
Daha sonra okuruz.
socket.async_receive(boost::asio::buffer (m_RecieveBuffer, m_BufLen),
                     handler);
std array
Şöyle yaparız.
std::array<char, 1024> recv_buf;

socket.async_receive(boost::asio::buffer(recv_buf),handler);

handler şöyledir.
void handle_receive (const boost::system::error_code& error)
{...}
async_send
char *
Bir string tanımlarız.
std::string m_SendBuffer;
Şöyle yaparız.
socket.async_send(boost::asio::buffer(m_SendBuffer.c_str,mSendBuffer.length()+1),
                  handler);
string
Şöyle yaparız.
std::string msg = "...";
socket.async_send (boost::asio::buffer(msg), handler);
async_write
Örnek ver.

close metodu
Şöyle yaparız.
socket.close();
close metodu
Şöyle yaparız.
boost::system::error_code errorcode;
socket.close(errorcode);
if(errorcode) {...}
else {...}
connect metodu - endpoint
TCP istemcisi açar. Eğer hata varsa boost::system::system_error exception fırlatılır.
boost::asio::ip::tcp::socket socket(ios);
boost::asio::ip::tcp::endpoint ep(...);
socket.open(boost::asio::ip::tcp::v4());
socket.connect(e) ;
Exception şöyledir.
boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector
  <boost::system::system_error> >'
what():  connect: Connection refused
connect metodu - endpoint + error code
Şöyle yaparız.
boost::asio::ip::tcp::endpoint e = ...;
socket.connect(endpoint, ec);
if(ec){
  cout<<"Port closed!"<<endl;
}else{
  cout<<"Port open!"<<endl;
} 
is_open metodu
is_open metodu muhtemelen şöyle çalışıyor.
int err = 0;
socklen_t size = sizeof (err);
int check = getsockopt (socket_fd, SOL_SOCKET, SO_ERROR, &err, &size);
if (check != 0) 
{
   //some code
}
open metodu
Şöyle yaparız.
boost::asio::ip::tcp::socket socket(io);
socket.open(boost::asio::ip::tcp::v4());
operator = metodu
Açıklaması şöyle
Following the move, the moved-from object is in the same state as if constructed using the basic_stream_socket(io_service&) constructor.
read_some metodu
Açıklaması şöyle
This method blocks until something gets received to the socket and then reads the data (while the read(...) function reads the whole file/socket until EOF, which only occurs if the connection drops)
read_some metodu - char []
read_some ve receive aynıdır. Şöyle yaparız.
unsigned char buf[max_incoming_wifi_data_length];

boost::system::error_code ec;

size_t length = socket.read_some (boost::asio::buffer(buf), ec);
read_some metodu - boost::array
Şöyle yaparız.
boost::array<char, 128> buf;
boost::system::error_code ec;

size_t length = socket.read_some (boost::asio::buffer(buf), ec);
read_some metodu - std::array
Şöyle yaparız.
std::array<char, 1024> buf;socket.read_some (boost::asio::buffer(buf));
read_somet metodu - std::string
Şöyle yaparız.
std::string recbuf;

//read data
sock.read_some(buffer(recbuf, 1024), ec);
//handle error
if (ec && ec != error::eof) {
  std::cout << "receive failed: " << ec.message() << std::endl;
}
else {
  std::cout << recbuf << std::endl;
}
receive metodu
Açıklaması şöyle.
The receive() operation may not receive all of the requested number of bytes. Consider using the read() function if you need to ensure that the requested amount of data is read before the blocking operation completes.
receive ve read_some aynıdır. Şöyle yaparız.
struct packet {
...
} receivedpacket;

socket.receive(boost::asio::buffer(receivedpacket));
receive - buffer + error code
Şöyle yaparız.
enum { max_length = 2048 };

boost::system::error_code ec;
char reply[max_length];

size_t bytes = s.receive(boost::asio::buffer(reply, max_length), 0, ec);
remote_endpoint metodu
Örnek
Şöyle yaparız.
boost::asio::ip::tcp::endpoint ep = socket.remote_endpoint();
Örnek
Şöyle yaparız.
_remoteAddress = socket.remote_endpoint().address(); //You may call to_string() on it
_remotePort = socket.remote_endpoint().port();
send metodu - Kullanma
Senkron çalışır ancak verinin tamamını göndermeyebilir. Bu yüzden kullanılmamalı. boost::asio::write(...) tercih edilmeli.

std::string için şöyle yaparız.
std::string str=...;
socket.send(boost::asio::buffer(str));
C tarzı string için şöyle yaparız.
socket.send(boost::asio::buffer("Message to client\r\n"));
set_option metodu
Örnek
Şöyle yaparız.
boost::asio::ip::tcp::socket::enable_connection_aborted eca(true);

socket.set_option(eca);
Örnek
Şöyle yaparız.
boost::asio::socket_base::keep_alive ka (true);
socket.set_option (ka);
Örnek
Şöyle yaparız.
socket.set_option (tcp::no_delay (true));
Şöyle yaparız.
boost::asio::ip::tcp::no_delay option(true);
socket.set_option(option);
shutdown metodu
Şöyle yaparız.
socket.shutdown (boost::asio::ip::tcp::socket::shutdown_both);
Şöyle yaparız.
socket.shutdown(asio::ip::tcp::socket::shutdown_send);
shutdown metodu - error_code
Şöyle yaparız.
// Send a TCP shutdown
boost::system::error_code ec;
socket.shutdown(tcp::socket::shutdown_send, ec);
write_some metodu - boost::array
Şöyle yaparız.
boost::array<char, 128> buf = ...;
boost::system::error_code ec;
socket.write_some(boost::asio::buffer(buf), error);
write_some metodu - std::string
Açıklaması şöyle
The write_some operation may not transmit all of the data to the peer. Consider using the write function if you need to ensure that all data is written before the blocking operation completes.
Senkron çalışır ancak verinin tamamını göndermeyebilir. Bu yüzden kullanılmamalı. 
boost::asio::write(...) tercih edilmeli. Şöyle yaparız.
std::string str =...;

socket.write_some(boost::asio::buffer (str));

Hiç yorum yok:

Yorum Gönder