PageRenderTime 32ms CodeModel.GetById 8ms app.highlight 20ms RepoModel.GetById 2ms app.codeStats 0ms

/src/Socket/Socket.cpp

https://github.com/Krozark/cpp-Socket
C++ | 208 lines | 159 code | 38 blank | 11 comment | 22 complexity | cb7227a99922e84507d39f34761b0ced MD5 | raw file
  1#include <utility>
  2#include <iostream>
  3
  4#include <Socket/Socket.hpp>
  5#include <Socket/FuncWrapper.hpp>
  6
  7#include <string.h>
  8
  9
 10namespace ntw {
 11//int Socket::max_id = 0;
 12
 13#if __WIN32
 14WSADATA Socket::WSAData;
 15#endif
 16
 17Socket::Socket(Socket::Domain domain,Socket::Type type,int protocole) : sock(INVALID_SOCKET), need_connect(type == Socket::Type::TCP), proto(protocole)
 18{
 19    //déclaration de la socket
 20    if((sock = ::socket(domain,type,proto)) == INVALID_SOCKET)
 21    {
 22        ::perror("socket()");
 23        throw SocketExeption("Invalid socket");
 24    }
 25
 26    ::memset((char*)&sock_cfg,0,sizeof(sock_cfg)); // mise a 0
 27    sock_cfg.sin_family = domain;
 28
 29};
 30
 31Socket::Socket(bool need_conn) : sock(INVALID_SOCKET), need_connect(need_conn),proto(0)
 32{
 33}
 34
 35Socket::~Socket()
 36{
 37    //shutdown();
 38    _close();
 39};
 40
 41bool Socket::connect(const std::string& host,int port)
 42{
 43    //sin_addr.s_addr =  adresse IP
 44    sock_cfg.sin_addr.s_addr = inet_addr(host.c_str());
 45    //sin_port = port à utiliser
 46    sock_cfg.sin_port = htons(port);
 47
 48    return connect();
 49};
 50
 51bool Socket::connect(int port)
 52{
 53    //sin_addr.s_addr =  adresse IP
 54    sock_cfg.sin_addr.s_addr = htonl(INADDR_ANY);
 55    //sin_port = port à utiliser
 56    sock_cfg.sin_port = htons(port);
 57
 58    return connect();
 59}
 60
 61bool Socket::connect()
 62{
 63    if(need_connect)
 64    {
 65        if(::connect(sock, (SOCKADDR*)&sock_cfg, sizeof(sockaddr)) != SOCKET_ERROR)
 66        {
 67            std::cerr<<"[Socket] <id:"<<sock<<">Connected to "<<inet_ntoa(sock_cfg.sin_addr)<<":"<<htons(sock_cfg.sin_port)<<std::endl;
 68            return true;
 69        }
 70        else
 71        {
 72            //std::cerr<<"[Socket] <id:"<<sock<<">Unable to connect"<<std::endl;
 73            return false;
 74        }
 75    }
 76    return true;
 77}
 78
 79bool Socket::disconnect()
 80{
 81    int domain;
 82    int type;
 83    socklen_t length = sizeof( int );
 84    bool res = true;
 85
 86    domain = sock_cfg.sin_family;
 87    if(::getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&type, &length )==0)
 88    {
 89        _close();
 90
 91        if((sock = ::socket(domain,type,proto)) == INVALID_SOCKET)
 92        {
 93            ::perror("socket()");
 94            throw SocketExeption("Invalid socket");
 95        }
 96
 97        ::memset((char*)&sock_cfg,0,sizeof(sock_cfg)); // mise a 0
 98        sock_cfg.sin_family = domain;
 99    }
100    else
101        res = false;
102
103    return res;
104}
105
106void Socket::bind()
107{
108    if(::bind(sock,(SOCKADDR*)&sock_cfg,sizeof(sock_cfg)) == SOCKET_ERROR)
109    {
110        perror("bind()");
111        throw SocketExeption("Unable to bind soket");
112    }
113}
114
115void Socket::listen(const int max_connexion)
116{
117    if(::listen(sock,max_connexion) == SOCKET_ERROR)
118    {
119        perror("listen()");
120        throw SocketExeption("Unable to listen");
121    }
122}
123
124void Socket::serverMode(int port,const int max_connexion,std::string host)
125{
126    //sin_addr.s_addr = adresse IP à utiliser
127    //IP automatiquement chopée
128    if(host.size() == 0)
129        sock_cfg.sin_addr.s_addr = htonl(INADDR_ANY);
130    else
131        sock_cfg.sin_addr.s_addr= inet_addr(host.c_str());
132
133    //sin_port = port à utiliser
134    sock_cfg.sin_port = htons(port);
135
136    bind();
137    listen(max_connexion);
138
139};
140
141Socket Socket::accept()
142{
143    Socket client(true);
144    accept(client);
145    return client;
146};
147
148void Socket::accept(Socket& client)
149{
150    socklen_t size = sizeof(sockaddr_in);
151    client.sock = ::accept(sock,(sockaddr*) &(client.sock_cfg), &size);
152    if (client.sock == INVALID_SOCKET)
153    {
154        perror("accept()");
155        throw SocketExeption("Invalid socket on accept");
156    }
157    std::cerr<<"[Socket] <id:"<<sock<<">New connexion accepted <id:"<<client.sock<<"> from "<<inet_ntoa(client.sock_cfg.sin_addr)<<":"<<htons(client.sock_cfg.sin_port)<<std::endl;
158};
159
160bool Socket::shutdown(Socket::Down mode)
161{
162    return ::shutdown(sock,mode) != -1;
163};
164
165std::string Socket::getIp() const
166{
167    return std::string(inet_ntoa(sock_cfg.sin_addr));
168}
169
170unsigned int Socket::getPort() const
171{
172    return htons(sock_cfg.sin_port);
173}
174
175bool Socket::setBroadcast(bool enable)
176{
177    int tmp = enable;
178    return ::setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(const char*)&tmp,sizeof(tmp)) == 0;
179}
180
181bool Socket::setReusable(bool enable)
182{
183    int tmp = enable;
184    return ::setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&tmp,sizeof(int)) == 0;
185}
186
187void Socket::init()
188{
189    #if __WIN32
190    WSAStartup(MAKEWORD(2,0),&Socket::WSAData);
191    #endif // __WIN32
192}
193
194void Socket::close()
195{
196     #if __WIN32
197    WSACleanup();
198    #endif // __WIN32
199}
200
201void Socket::_close()
202{
203    if(sock != INVALID_SOCKET)
204        closesocket(sock);
205}
206
207};
208