source: BAORadio/libindi/libindi/BAOTest/Socket.cpp @ 493

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

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

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