source: BAORadio/libindi/v1.0.1/drivers/telescope/Socket.cpp @ 614

Last change on this file since 614 was 493, checked in by frichard, 14 years ago

Le programme gère mieux les connexion/déconnexion des microcontrôleurs.

File size: 4.6 KB
Line 
1// Implementation of the Socket class.
2
3
4#include "Socket.h"
5#include "string.h"
6#include <string.h>
7#include <errno.h>
8#include <fcntl.h>
9#include <iostream>
10#include <netinet/tcp.h>
11
12
13
14Socket::Socket() :
15        m_sock ( -1 )
16{
17
18    memset ( &m_addr,
19             0,
20             sizeof ( m_addr ) );
21}
22
23Socket::~Socket()
24{
25    if ( is_valid() )
26        ::close ( m_sock );
27}
28
29bool Socket::create()
30{
31    m_sock = socket ( AF_INET,
32                      SOCK_STREAM,
33                      0); //IPPROTO_TCP
34
35    if ( ! is_valid() )
36        return false;
37
38
39    int on = 1;
40
41    if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ) return false;
42
43    // Réduire les délais lors des transmissions TCP/IP
44    // Voir article à l'adresse
45    // http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Realtime_Tuning_Guide/sect-Realtime_Tuning_Guide-Application_Tuning_and_Deployment-TCP_NODELAY_and_Small_Buffer_Writes.html
46   
47    if ( setsockopt(m_sock, SOL_TCP, TCP_NODELAY, (const char*) &on, sizeof(on)) < 0 ) return false;
48
49    return true;
50}
51
52
53
54bool Socket::bind ( const int port )
55{
56    if ( ! is_valid() ) return false;
57   
58    m_addr.sin_family = AF_INET;
59    m_addr.sin_addr.s_addr = INADDR_ANY;
60    m_addr.sin_port =  htons ( port );
61
62    int bind_return = ::bind ( m_sock,
63                               ( struct sockaddr * ) &m_addr,
64                               sizeof ( m_addr ) );
65
66
67    if ( bind_return == -1 ) return false;
68   
69    return true;
70}
71
72
73bool Socket::listen() const
74{
75    if ( ! is_valid() ) return false;
76   
77    int listen_return = ::listen ( m_sock, MAXCONNECTIONS );
78
79    if ( listen_return == -1 ) return false;
80   
81    return true;
82}
83
84
85bool Socket::accept ( Socket& new_socket ) const
86{
87    int addr_length = sizeof ( m_addr );
88   
89    new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
90
91    if ( new_socket.m_sock <= 0 ) return false;
92       
93    return true;
94}
95
96
97bool Socket::shutdown()
98{
99  int ret = 0;
100
101  if ( is_valid() )
102      ret =  ::shutdown ( m_sock, 2 );
103 
104  m_sock=-1;
105
106  if ( ret == 0 ) return true;
107
108  return false;
109}
110
111
112bool Socket::send ( const std::string s ) const
113{
114    if ( ! is_valid() ) return false;
115   
116    int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL);
117   
118    if ( status == -1 ) return false;
119       
120    return true;   
121}
122
123
124int Socket::recv ( std::string& s ) const
125{
126    int sel;
127    fd_set r;
128    struct timeval timeout;
129   
130    if ( ! is_valid() ) return false;
131   
132    s="";
133
134    timeout.tv_sec = 0; // initialise le timeout, ici  les secondes
135    timeout.tv_usec = 1; // les microsecondes
136
137    FD_ZERO(&r); // initialise la liste de fd
138    FD_SET(m_sock, &r); // ajoute la socket dans la liste des fd
139    sel = select(m_sock + 1, &r, NULL, NULL, &timeout);
140    if (sel < 0) // select a rencontré un problÚme
141    {
142        return -1;
143    }
144    else if (sel == 0) // timeout
145    {
146        return 1;
147    }
148    else // quelque chose est à lire sur un file descriptor
149    {
150        if (FD_ISSET(m_sock, &r)) // si la socket est prête à être lue
151        {
152            char buf [ MAXRECV + 1 ];
153
154            s = "";
155
156            memset ( buf, 0, MAXRECV + 1 );
157
158            int status = ::recv ( m_sock, buf, MAXRECV, 0 );
159
160            if ( status == -1 )
161            {
162                 // là, nous ne sommes pas en présence d'une vraie erreur
163                 // car le mode non-bloquant est activé ici
164                 // (consulter la doc de la fct recv...)
165                 if (errno == EAGAIN )
166                 {
167                   return 0;
168                 }
169                 
170                 return -1;
171            }
172            else if ( status == 0 )
173            {
174                return 0;
175            }
176            else
177            {
178                s = buf;
179                return status;
180            }
181        }
182    }
183}
184
185
186
187bool Socket::connect ( const std::string host, const int port )
188{
189    if ( ! is_valid() ) return false;
190   
191    memset ( &m_addr,
192             0,
193             sizeof ( m_addr ) );
194
195
196    m_addr.sin_family = AF_INET;
197    m_addr.sin_port = htons ( port );
198
199    int status = inet_pton ( AF_INET, host.c_str(), &m_addr.sin_addr );
200
201    if ( errno == EAFNOSUPPORT ) return false;
202
203    status = ::connect ( m_sock, ( sockaddr * ) &m_addr, sizeof ( m_addr ) );
204
205    if ( status == 0 ) return true;
206   
207    return false;
208}
209
210void Socket::set_non_blocking ( const bool b )
211{
212    int opts;
213
214    opts = fcntl ( m_sock,F_GETFL );
215
216    if ( opts < 0 )
217    {
218        return;
219    }
220
221    if ( b )
222        opts = ( opts | O_NONBLOCK );
223    else
224        opts = ( opts & ~O_NONBLOCK );
225
226    fcntl ( m_sock,
227            F_SETFL,opts );
228
229}
230
231
232std::string Socket::recupip() const
233{
234    return inet_ntoa(m_addr.sin_addr);
235}
Note: See TracBrowser for help on using the repository browser.