Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

Программирование сокетов в Linux на C++.By Rob Tougher

Сокет - это механизм обмена данными между процессами . Процессы могут находиться и на одной машине , и на разных . После установки коннекта обмен данными может происходить в обоих направлениях. Данная версия реализована с помощью т.н. raw socket . Приложение традиционно состоит из клиента и сервера , которые реализованы с помощью классов ClientSocket и ServerSocket.

2. Взаимодействие клиент-сервер

Следующая таблица показывает последовательность такого взаимодействия.
Server Client
1. Установка слушающего сокета и ожидание запроса от клиента.  
  2. Создание клиентского сокета и попытка законнектиться на сервер.
3. Вылавливание клиентского коннекта.  
4. Отправка-получение данных 4. Отправка-получение данных.
5. Закрытие коннекта. 5. Закрытие коннекта.
 

Реализация простого сервера и клиента

Сервер - инициализация слушающего сокета : #include "ServerSocket.h" #include "SocketException.h" #include <string> int main ( int argc, int argv[] ) { try { // Create the server socket ServerSocket server ( 30000 ); // rest of code - // accept connection, handle request, etc... } catch ( SocketException& e ) { std::cout << "Exception :" << e.description() << "\nExiting.\n"; } return 0; } Конструктор для ServerSocket инициализирует слушающий сокет . Реализация класса ServerSocket : // Implementation of the ServerSocket class #include "ServerSocket.h" #include "SocketException.h" ServerSocket::ServerSocket ( int port ) { if ( ! Socket::create() ) { throw SocketException ( "Could not create server socket." ); } if ( ! Socket::bind ( port ) ) { throw SocketException ( "Could not bind to port." ); } if ( ! Socket::listen() ) { throw SocketException ( "Could not listen to socket." ); } } ServerSocket::~ServerSocket(){} const ServerSocket& ServerSocket::operator << ( const std::string& s ) const { if ( ! Socket::send ( s ) ) { throw SocketException ( "Could not write to socket." ); } return *this; } const ServerSocket& ServerSocket::operator >> ( std::string& s ) const { if ( ! Socket::recv ( s ) ) { throw SocketException ( "Could not read from socket." ); } return *this; } void ServerSocket::accept ( ServerSocket& sock ) { if ( ! Socket::accept ( sock ) ) { throw SocketException ( "Could not accept socket." ); } } Обратите внимание на блок try/catch block. Классы ServerSocket и ClientSocket используют традиционную С++ обработку исключений . Обработка исключений описана в SocketException.h: // SocketException class #ifndef SocketException_class #define SocketException_class #include < string > class SocketException { public: SocketException ( std::string s ) : m_s ( s ) {}; ~SocketException (){}; std::string description() { return m_s; } private: std::string m_s; }; #endif Метод description() этого класса описывает саму ошибку . Теперь клиент : #include "ClientSocket.h" #include "SocketException.h" #include <iostream> #include <string> int main ( int argc, int argv[] ) { try { // Create the client socket ClientSocket client_socket ( "localhost", 30000 ); // rest of code - // send request, retrieve reply, etc... } catch ( SocketException& e ) { std::cout << "Exception :" << e.description() << "\n"; } return 0; } При создании инстанса класса ClientSocket клиентский сокет коннектится к хосту/порту . Далее сервер слушает клиента и фиксирует попытки коннекта . Чуть доработанная версия сервера : #include "ServerSocket.h" #include "SocketException.h" #include <string> int main ( int argc, int argv[] ) { try { // Create the socket ServerSocket server ( 30000 ); while ( true ) { ServerSocket new_sock; server.accept ( new_sock ); // rest of code - // read request, send reply, etc... } } catch ( SocketException& e ) { std::cout << "Exception :" << e.description() << "\nExiting.\n"; } return 0; } Отлавливание клиентских коннектов выполняется с помощью метода accept , который имеет параметр new_sock . После того как мы поймали клиента , ему нужно дать знать об этом . Одной из фич С++ является способность перегружать операторы , или создавать собственный вариант оператора . В классах ClientSocket и ServerSocket перегружаются стандартные операторы ввода-вывода << и >> : #include "ServerSocket.h" #include "SocketException.h" #include <string> int main ( int argc, int argv[] ) { try { // Create the socket ServerSocket server ( 30000 ); while ( true ) { ServerSocket new_sock; server.accept ( new_sock ); try { while ( true ) { std::string data; new_sock >> data; new_sock << data; } } catch ( SocketException& ) {} } } catch ( SocketException& e ) { std::cout << "Exception :" << e.description() << "\nExiting.\n"; } return 0; } new_sock включает в себя всю информацию о сокете и используется для обмена данных с клиентом. Строка "new_sock >> data;" читает данные из сокета и помещает их в строку 'data'." Следующая строка посылает 'data' назад клиенту . Это пример эхо-сервера . При этом клиент распечатывает ответ сервера : #include "ClientSocket.h" #include "SocketException.h" #include <iostream> #include <string> int main ( int argc, int argv[] ) { try { ClientSocket client_socket ( "localhost", 30000 ); std::string reply; try { client_socket << "Test message."; client_socket >> reply; } catch ( SocketException& ) {} std::cout << "response from the server:\n\"" << reply << "\"\n";; } catch ( SocketException& e ) { std::cout << "Exception was caught:" << e.description() << "\n"; } return 0; } В данный проект входят следующие файлы :
Miscellaneous:
Makefile - the Makefile for this project
Socket.h, Socket.cpp - the Socket class, which implements the raw socket API calls.
SocketException.h - the SocketException class
Server:
simple_server_main.cpp - main file
ServerSocket.h, ServerSocket.cpp - the ServerSocket class
Client:
simple_client_main.cpp - main file
ClientSocket.h, ClientSocket.cpp - the ClientSocket class
Их можно целиком взять в архиве тут (10 кб) . После компиляции будут созданы 2 бинарника . Запускаем сервер :
prompt$ ./simple_server running.... Теперь запускаем клиента : prompt$ ./simple_client We received this response from the server: "Test message." prompt$ Клиент посылает данные серверу , читает ответ и печатает его .
Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье
Мишаня
  я не очень силен в С++, скачав архив при компиляции возникают ошибки,
версия компилятора
gcc version 3.2.3 (ALT Linux, build 3.2.3-alt3)

2006-02-09 14:32:42
JO
  жуть просто
одно s=buf чего стоит
я уже не говорю про close в деструкторе
ЛЮДИ!!! даже не пытайтесь юзать этот бред - кроме проблем ничего не получите
2008-05-09 23:30:12
Дмитрий
  так я не понял допустим я хочу одиночную игру сделать онлайн то мне надо что то качать программы для мулбтиплеера все эти
 атрибуты 
2012-12-03 22:08:22
Влад
  Я хочу ту же Готику 3 воплотить в онлайн, ну то есть в мультиплеер как это сделать
покажи видео урок поучительный расскажи подробно если захочешь? 
2012-12-03 22:12:19